|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.