Annotation of Examples/DriverKit/AMDPCSCSIDriver/README.rtf, revision 1.1.1.1

1.1       root        1: {\rtf0\ansi{\fonttbl\f2\fmodern Courier;\f1\fmodern Ohlfs;}
                      2: \paperw13040
                      3: \paperh8220
                      4: \margl20
                      5: \margr120
                      6: {\colortbl;\red0\green0\blue0;}
                      7: \pard\tx1140\tx2300\tx3440\tx4600\tx5760\tx6900\tx8060\tx9200\tx10360\tx11520\f2\b\i0\ulnone\fs28\fc1\cf1              AMD 53C974/79C974 SCSI Driver Design Notes\
                      8: 
                      9: \f1\b0\fs24\fc0\cf0            \
                     10:     \
                     11: 
                     12: \pard\tx720\tx2300\tx3440\tx4600\tx5760\tx6900\tx8060\tx9200\tx10360\tx11520\f2\b\fs28\fc0\cf0 1.      General\
                     13: 
                     14: \pard\tx1140\tx2300\tx3440\tx4600\tx5760\tx6900\tx8060\tx9200\tx10360\tx11520\fc0\cf0 \
                     15: 
                     16: \f1\b0\fs24\li720\fc1\cf1 This driver is primarily intended to be used with the AMD 79C974 PCnet-SCSI combo chip, which combines an Ethernet Controller, a SCSI Host Adapter, and a PCI Bus Interface module on one chip. This driver only controls the SCSI logic on the 79C974; a separate driver is used for the Ethernet logic. The driver also should work with the AMD 53C974, a subset of the 79C974. (This has not been tested as of 25 Jan, 1995.) The 53C974 is, in turn, a superset of the old NCR 53C90A chip, which was the SCSI controller used on all NeXT ("Black") hardware.\
                     17: \
                     18: This driver implements the following features:\
                     19: \
                     20: � Disconnect/Reselect\
                     21: � 10 MB/s "Fast SCSI" Synchronous Transfers\
                     22: � SCSI-2 Command Queueing \
                     23: � Auto Request Sense\
                     24:  \
                     25: Synchronous Mode, Command Queueing, and Fast SCSI can be disabled and enabled for the driver as a whole via the driver instance's Instance table. There is a Custom Device Inspector used by the Configure App which allows the user to specify these parameters. Per-target disable flags for Command Queueing and Synchronous Mode are also kept for both of the features, so that if a target rejects an attempt to use the mode (typically via a "Message Reject" message), no further attempts will be made to use the feature with that target. Synchronous Transfer offset and period are also negotiated and kept on a per-target basis, per the SCSI-2 specification. \
                     26: \
                     27: \
                     28: 
                     29: \pard\tx720\tx2300\tx3440\tx4600\tx5760\tx6900\tx8060\tx9200\tx10360\tx11520\f2\b\fs28\fc0\cf0 2.      Architecture\
                     30: 
                     31: \pard\tx1140\tx2300\tx3440\tx4600\tx5760\tx6900\tx8060\tx9200\tx10360\tx11520\fc0\cf0 \
                     32: 
                     33: \f1\b0\fs24\li720\fc1\cf1 Unlike most other SCSI Host Adapter drivers for the Intel Platform, this driver is involved in a lot of low-level SCSI events, including dealing with phase changes, setting ATN at appropriate times, doing synchronous transfer negotiation, etc. The driver has to maintain quite a bit of state to keep track of what is occurring on the bus and typically responds to 3 or 4 interrupts for every SCSI command.\
                     34: \
                     35: The driver is implemented as a subclass of 
                     36: \f2\b\fs28 IOSCSIController
                     37: \f1\b0\fs24  called 
                     38: \f2\b\fs28 AMD_SCSI
                     39: \f1\b0\fs24 . 
                     40: \f2\b\fs28 IOSCSIController
                     41: \f1\b0\fs24  is a subclass of 
                     42: \f2\b\fs28 IODirectDevice
                     43: \f1\b0\fs24 . The 
                     44: \f2\b\fs28 IODirectDevice
                     45: \f1\b0\fs24  categories 
                     46: \f2\b\fs28 IOEISADirectDevice
                     47: \f1\b0\fs24  and 
                     48: \f2\b\fs28 IOPCIDirectDevice
                     49: \f1\b0\fs24  are also used by 
                     50: \f2\b\fs28 AMD_SCSI
                     51: \f1\b0\fs24 .\
                     52: \
                     53: \
                     54: 
                     55: \f2\b\fs28\fc0\cf0 Control Flow and the I/O thread\
                     56: 
                     57: \f1\b0\fs24\fc1\cf1 \
                     58: The control flow in the driver is the same as for all other NextStep SCSI drivers - all access to the hardware is done by one thread, the I/O thread. This eliminates the need for locks around accesses to the hardware and other critical resources. All communication with the I/O thread by exported methods is performed by passing a command struct, called a 
                     59: \f2\b\fs28 commandBuf
                     60: \f1\b0\fs24 , to the I/O thread via the instance variable 
                     61: \f2\b\fs28 commandQ
                     62: \f1\b0\fs24 . 
                     63: \f2\b\fs28 CommandQ
                     64: \f1\b0\fs24  is protected by 
                     65: \f2\b\fs28 commandLock
                     66: \f1\b0\fs24 . After enqueueing a 
                     67: \f2\b\fs28 commandBuf
                     68: \f1\b0\fs24  on 
                     69: \f2\b\fs28 commandQ
                     70: \f1\b0\fs24 , a message with a 
                     71: \f2\b\fs28 msg_id
                     72: \f1\b0\fs24  of 
                     73: \f2\b\fs28 IO_COMMAND_MSG
                     74: \f1\b0\fs24  is sent to the driver's interrupt port. The I/O thread is the only code which does a 
                     75: \f2\b\fs28 msg_receive()
                     76: \f1\b0\fs24  on the interrupt port. Subsequent to initialization, 
                     77: \f2\b\fs28 commandQ
                     78: \f1\b0\fs24  and 
                     79: \f2\b\fs28 commandLock
                     80: \f1\b0\fs24  are the only data shared by exported methods and the I/O thread.\
                     81: \
                     82: I/O complete notification is performed via 
                     83: \f2\b\fs28 commandBuf.cmdLock
                     84: \f1\b0\fs24 , which is an 
                     85: \f2\b\fs28 NXConditionLock
                     86: \f1\b0\fs24 . Exported methods wait on this lock after passing a 
                     87: \f2\b\fs28 commandBuf
                     88: \f1\b0\fs24  to the I/O thread. \
                     89: \
                     90: Subsequent to initialization, the only methods in the driver which do 
                     91: \f2\b\i\fs28 not
                     92: \f1\b0\i0\fs24  run solely as part of the I/O thread are:\
                     93: \
                     94: 
                     95: \f2\b\fs28     -executeRequest:buffer:client:\
                     96:        -resetSCSIBus\
                     97:        -resetStats\
                     98:        -numQueueSamples\
                     99:        -sumQueueLengths\
                    100:        -maxQueueLength\
                    101:        -executeCmdBuf\
                    102: 
                    103: \f1\b0\fs24  \
                    104: These are all found in 
                    105: \f2\b\fs28 AMD_SCSI.m
                    106: \f1\b0\fs24 . (Note: unless otherwise indicated, all files referred to in this document reside in the AMD53C974SCSIDriver_reloc.tproj directory of the driver project.) The first two methods are exported methods used for normal SCSI I/O and are called by indirect SCSI devices like SCSIDisk and SCSITape. The next four are associated with gathering statistics and are called from IOSCSIController. The last one, 
                    107: \f2\b\fs28 -executeCmdBuf
                    108: \f1\b0\fs24 , is the common means by which 
                    109: \f2\b\fs28 -executeRequest:buffer:client: 
                    110: \f1\b0\fs24 and
                    111: \f2\b\fs28  -resetSCSIBus 
                    112: \f1\b0\fs24 pass 
                    113: \f2\b\fs28 commandBuf
                    114: \f1\b0\fs24 s to the I/O thread and wait for completion.\
                    115: \
                    116: \
                    117: 
                    118: \f2\b\fs28\fc0\cf0 Processing of commands by the I/O thread\
                    119: \
                    120: 
                    121: \f1\b0\fs24\fc1\cf1 The I/O thread's job is basically to dequeue commands from 
                    122: \f2\b\fs28 commandQ
                    123: \f1\b0\fs24 , start up SCSI transactions on the 79C974, and deal with interrupts. All of the 
                    124: \f2\b\fs28 msg_receive()
                    125: \f1\b0\fs24 s which fetch command requests and interrupt events from the driver's interrupt port are done by 
                    126: \f2\b\fs28 IODirectDevice
                    127: \f1\b0\fs24 's I/O Thread. If a command message is received, 
                    128: \f2\b\fs28 IODirectDevice
                    129: \f1\b0\fs24  calls 
                    130: \f2\b\fs28 -commandRequestOccurred
                    131: \f1\b0\fs24 . If an interrupt message is received, 
                    132: \f2\b\fs28 -interruptOccurred
                    133: \f1\b0\fs24  is called. Both of these methods are implemented by the 
                    134: \f2\b\fs28 AMD_SCSI
                    135: \f1\b0\fs24  class. \
                    136: \
                    137: When an exported method passes a 
                    138: \f2\b\fs28 commandBuf 
                    139: \f1\b0\fs24 to the I/O thread, it is quite possible that the I/O thread can not immediately process the command due to the fact that there is already a command active on the SCSI bus at that time. If this occurs, the incoming command is enqueued on 
                    140: \f2\b\fs28 pendingQ
                    141: \f1\b0\fs24 . (Note that the decision as to whether a command can be processed, and the act of enqueueing a command on 
                    142: \f2\b\fs28 pendingQ
                    143: \f1\b0\fs24 , are solely the responsibility of the I/O thread. There are no races or deadlock conditions here.) Whenever the I/O thread detects a "Bus Free" condition, it will look at 
                    144: \f2\b\fs28 pendingQ
                    145: \f1\b0\fs24 , and if the queue is non-empty, the first 
                    146: \f2\b\fs28 commandBuf
                    147: \f1\b0\fs24  in the queue is dequeued and used to start up a new SCSI transaction. \
                    148: \
                    149: The 
                    150: \f2\b\fs28 commandBuf
                    151: \f1\b0\fs24  associated with the currently active SCSI transaction is always kept in 
                    152: \f2\b\fs28 activeCmd
                    153: \f1\b0\fs24 . If 
                    154: \f2\b\fs28 activeCmd
                    155: \f1\b0\fs24  is NULL, the SCSI bus is either free, or there is a reselection in progress for which we do not have complete target/LUN/queue tag information. \
                    156: \
                    157: When an active SCSI target disconnects (as opposed to doing a "Command Complete"), the I/O thread places the associated 
                    158: \f2\b\fs28 commandBuf
                    159: \f1\b0\fs24  on 
                    160: \f2\b\fs28 disconnectQ
                    161: \f1\b0\fs24 . Whenever a reselection occurs, 
                    162: \f2\b\fs28 disconnectQ
                    163: \f1\b0\fs24  is scanned for a commandBuf which matches the reselecting target, LUN, and (possibly) queue tag. If a match is found, the 
                    164: \f2\b\fs28 commandBuf
                    165: \f1\b0\fs24  is dequeued from 
                    166: \f2\b\fs28 disconnectQ
                    167: \f1\b0\fs24  and becomes 
                    168: \f2\b\fs28 activeCmd
                    169: \f1\b0\fs24 .\
                    170: \
                    171: The driver contains logic to prevent sending a command to a target/LUN nexus which currently has an active, but disconnected, command - unless command queueing is enabled for the driver, and is not disabled for the given target. This allows higher layers in the system (e.g., SCSIDisk) to enqueue multiple requests for one target and LUN without worrying about the nexus's current state. This logic uses the array 
                    172: \f2\b\fs28 activeArray[][]
                    173: \f1\b0\fs24 , which is an array of counters which keep track of how many I/Os are active on a per-LUN basis. When command queueing is disabled (either globally, or on a per-target basis), an 
                    174: \f2\b\fs28 activeArray
                    175: \f1\b0\fs24  counter has a maximum value of 1. If command queueing is enabled, an 
                    176: \f2\b\fs28 activeArray
                    177: \f1\b0\fs24  counter has a maximum value of the target's queue length (if known). See the 
                    178: \f2\b\fs28 -cmdBufOk:
                    179: \f1\b0\fs24  method, in AMD_SCSI.m, for the implementation of the decision as to whether a target/lun nexus is ready to accept a new command.\
                    180: \
                    181: \
                    182: 
                    183: \pard\tx720\tx2300\tx3440\tx4600\tx5760\tx6900\tx8060\tx9200\tx10360\tx11520\f2\b\fs28\fc0\cf0 3.      Organization\
                    184: 
                    185: \pard\tx1140\tx2300\tx3440\tx4600\tx5760\tx6900\tx8060\tx9200\tx10360\tx11520\fc0\cf0 \
                    186: 
                    187: \f1\b0\fs24\li720\fc1\cf1 The driver was organized to facilitate porting to other platforms using chips similar to the 79C974, and also to other "dumb" host adapter chips on the x86 platform. With some exceptions, all of the logic which is independent of either the chip or the host bus is contained in 
                    188: \f2\b\fs28 AMD_SCSI.m
                    189: \f1\b0\fs24 . All of the logic which deals directly with the 79C974 is contained in 
                    190: \f2\b\fs28 AMD_Chip.m 
                    191: \f1\b0\fs24 and
                    192: \f2\b\fs28  AMD_ChipPrivate.m.
                    193: \f1\b0\fs24  All of the logic which is specific to the x86 architecture and the PCI bus is contained in 
                    194: \f2\b\fs28 AMD_x86.m
                    195: \f1\b0\fs24 . The API to 
                    196: \f2\b\fs28 AMD_Chip.m 
                    197: \f1\b0\fs24 which is public to the other parts of the driver consists of six methods:\
                    198: \
                    199: � 
                    200: \f2\b\fs28 -probeChip
                    201: \f1\b0\fs24 , performs one-time-only initialization.\
                    202: � 
                    203: \f2\b\fs28 -hwReset
                    204: \f1\b0\fs24 , reusable chip reset/init.\
                    205: � 
                    206: \f2\b\fs28 -scsiReset
                    207: \f1\b0\fs24 , performs SCSI reset.\
                    208: � 
                    209: \f2\b\fs28 -hwStart:
                    210: \f1\b0\fs24 , starts up a new SCSI transaction.\
                    211: � 
                    212: \f2\b\fs28 -hwInterrupt
                    213: \f1\b0\fs24 , deals with an interrupt event.\
                    214: � 
                    215: \f2\b\fs28 -logRegs
                    216: \f1\b0\fs24 , a debugging function to dump registers to the console.\
                    217: 
                    218: \f2\b\fs28\fc0\cf0 \
                    219: 
                    220: \f1\b0\fs24\fc1\cf1 When porting this driver to a new chip, these six methods are pretty much all that need to be re-implemented (in addition to any private, implementation-specific methods needed for the new chip). \
                    221: \
                    222: The design goal of separating out the chip-specific, architecture-specific, and hardware-independent functionality into separate modules was not religiously adhered to. Sometimes, for example in the routines to handle DMA in 
                    223: \f2\b\fs28 AMD_x86.m
                    224: \f1\b0\fs24 , there is a mixture of chip- and bus-specific functions in one file (or even one method). The tradeoff between design clarity and portability went towards design clarity in these cases.\
                    225: \
                    226: \
                    227: 
                    228: \pard\tx720\tx2300\tx3440\tx4600\tx5760\tx6900\tx8060\tx9200\tx10360\tx11520\f2\b\fs28\fc0\cf0 4.      File contents\
                    229: 
                    230: \pard\tx1140\tx2300\tx3440\tx4600\tx5760\tx6900\tx8060\tx9200\tx10360\tx11520\fc0\cf0 \
                    231: 
                    232: \f1\b0\fs24\li720\fc1\cf1 The following files all exist in the AMD53C974SCSIDriver_reloc.tproj directory. (AMD53C974SCSIDriver_reloc is the driver's loadable binary.)\
                    233: \
                    234: \
                    235: AMD_SCSI.h\
                    236: \
                    237: 
                    238: \fi-20\li1160 Exported interface to the driver. Typically used by SCSI indirect drivers like SCSIDisk and SCSITape.\
                    239: \
                    240: 
                    241: \fi0\li720 AMD_Private.h\
                    242: 
                    243: \li0 \
                    244: 
                    245: \fi-20\li1160 Private hardware-independent methods.\
                    246: \
                    247: 
                    248: \fi0\li720 AMD_Types.h\
                    249: 
                    250: \li0 \
                    251: 
                    252: \fi-20\li1160 Private structs and #defines used by the entire driver. \
                    253: \
                    254: 
                    255: \fi0\li720 AMD_SCSI.m\
                    256: 
                    257: \li0 \
                    258: 
                    259: \fi-20\li1160 Implementation of AMD_SCSI.h and AMD_Private.h methods.\
                    260: \
                    261: 
                    262: \fi0\li720 AMD_x86.[hm]\
                    263: 
                    264: \li0 \
                    265: 
                    266: \fi-20\li1160 Methods specific to Intel platform and PCI bus.\
                    267: \
                    268: 
                    269: \fi0\li720 AMD_Chip.[hm]\
                    270: 
                    271: \li0 \
                    272: 
                    273: \fi-20\li1160 Chip-specific methods available to the rest of the driver.\
                    274: \
                    275: 
                    276: \fi0\li720 AMD_ChipPrivate.m\
                    277: 
                    278: \li0 \
                    279: 
                    280: \fi-20\li1160 Chip-specific methods available only to AMD_Chip.m.\
                    281: \
                    282: 
                    283: \fi0\li720 AMD_Regs.h\
                    284: 
                    285: \li0 \
                    286: 
                    287: \fi-20\li1160 Definitions of AMD 79C974 registers.\
                    288: \
                    289: 
                    290: \fi0\li720 bringup.h\
                    291: 
                    292: \li0 \
                    293: 
                    294: \fi-20\li1160 Debugging and bringup flags.\
                    295: \
                    296: 
                    297: \fi0\li720 AMD_ddm.h\
                    298: 
                    299: \li0 \
                    300: 
                    301: \fi-20\li1160 #defines used for DDM calls.\
                    302: \
                    303: 
                    304: \fi0\li720 AMD.ddm\
                    305: 
                    306: \li0 \
                    307: 
                    308: \fi-20\li1160 Config file used by DDMViewer.\
                    309: \
                    310: 
                    311: \fi0\li720 ioPorts.[ch]\
                    312: 
                    313: \li0 \
                    314: 
                    315: \fi-20\li1160 A DEBUG version of <driverkit/i386/ioPorts.h>.\
                    316: \
                    317: 
                    318: \fi0\li720 pciConf.h\
                    319: 
                    320: \li0 \
                    321: 
                    322: \fi-20\li1160 #defines for PCI configuration registers.\
                    323: \
                    324: 
                    325: \fi0\li720 configKeys.h\
                    326: 
                    327: \li0 \
                    328: 
                    329: \fi-20\li1160 String definition for keys in driver's config table.\
                    330: \
                    331: 
                    332: \fi0\li720 Makefile.driver_preamble \
                    333: Makefile.preamble\
                    334: Makefile.postamble\
                    335: 
                    336: \li0 \
                    337: 
                    338: \fi-20\li1160 Standard Makefile additions, common to all drivers.\
                    339: \
                    340: \
                    341: 
                    342: \f2\b\fs28\fi0\li720 Other Files
                    343: \f1\b0\fs24 \
                    344: \
                    345: Here is a brief description of the other files residing in the driver project's root directory. \
                    346: \
                    347: \
                    348: SCSIInspector.[mh]\
                    349: \
                    350: 
                    351: \fi-20\li1160 Custom Device Inspector for use in the Configure App.\
                    352: \
                    353: 
                    354: \fi0\li720 Default.table \
                    355: \
                    356: 
                    357: \fi-20\li1160 Template used by Configure App for creating Instance tables.\
                    358: \
                    359: 
                    360: \fi0\li720 English.lproj/AMDInspector.nib\
                    361: \
                    362: 
                    363: \fi-20\li1160 Localizable nib file for Custom Device Inspector. \
                    364: 
                    365: \fi0\li720 \
                    366: English.lproj/Localizable.strings\
                    367: \
                    368: 
                    369: \fi-20\li1160 Localizable strings file used by Configure App.\
                    370: 
                    371: \fi0\li720 \
                    372: English.lproj/DriverHelp/*\
                    373:    \
                    374:    Support for on-line help in the Configure App. \
                    375:    \
                    376: Makefile \
                    377: PB.project \
                    378: \
                    379: 
                    380: \fi-20\li1160 Created by Project Builder.\
                    381: 
                    382: \fi0\li720 \
                    383: SGS_ENV\
                    384: \
                    385: 
                    386: \fi-20\li1160 For NeXT internal use.\
                    387: \
                    388: 
                    389: \fi0\li720 Makefile.postamble\
                    390: Makefile.preamble\
                    391: \
                    392: 
                    393: \fi-20\li1160 Standard Makefile additions, common to all drivers.\
                    394: 
                    395: \fi0\li720 \
                    396: changes\
                    397: \
                    398: 
                    399: \fi-20\li1160 Revision history of this project.\
                    400: \
                    401: 
                    402: \fi0\li720 README.rtf\
                    403: \
                    404: 
                    405: \fi-20\li1160 This file.\
                    406: 
                    407: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.