1*191d7ec1SSascha Wildner/* $FreeBSD: src/sys/dev/isp/DriverManual.txt,v 1.3 2011/11/11 22:27:09 eadler Exp $ */ 2*191d7ec1SSascha Wildner 3*191d7ec1SSascha Wildner Driver Theory of Operation Manual 4*191d7ec1SSascha Wildner 5*191d7ec1SSascha Wildner1. Introduction 6*191d7ec1SSascha Wildner 7*191d7ec1SSascha WildnerThis is a short text document that will describe the background, goals 8*191d7ec1SSascha Wildnerfor, and current theory of operation for the joint Fibre Channel/SCSI 9*191d7ec1SSascha WildnerHBA driver for QLogic hardware. 10*191d7ec1SSascha Wildner 11*191d7ec1SSascha WildnerBecause this driver is an ongoing project, do not expect this manual 12*191d7ec1SSascha Wildnerto remain entirely up to date. Like a lot of software engineering, the 13*191d7ec1SSascha Wildnerultimate documentation is the driver source. However, this manual should 14*191d7ec1SSascha Wildnerserve as a solid basis for attempting to understand where the driver 15*191d7ec1SSascha Wildnerstarted and what is trying to be accomplished with the current source. 16*191d7ec1SSascha Wildner 17*191d7ec1SSascha WildnerThe reader is expected to understand the basics of SCSI and Fibre Channel 18*191d7ec1SSascha Wildnerand to be familiar with the range of platforms that Solaris, Linux and 19*191d7ec1SSascha Wildnerthe variant "BSD" Open Source systems are available on. A glossary and 20*191d7ec1SSascha Wildnera few references will be placed at the end of the document. 21*191d7ec1SSascha Wildner 22*191d7ec1SSascha WildnerThere will be references to functions and structures within the body of 23*191d7ec1SSascha Wildnerthis document. These can be easily found within the source using editor 24*191d7ec1SSascha Wildnertags or grep. There will be few code examples here as the code already 25*191d7ec1SSascha Wildnerexists where the reader can easily find it. 26*191d7ec1SSascha Wildner 27*191d7ec1SSascha Wildner2. A Brief History for this Driver 28*191d7ec1SSascha Wildner 29*191d7ec1SSascha WildnerThis driver originally started as part of work funded by NASA Ames 30*191d7ec1SSascha WildnerResearch Center's Numerical Aerodynamic Simulation center ("NAS" for 31*191d7ec1SSascha Wildnershort) for the QLogic PCI 1020 and 1040 SCSI Host Adapters as part of my 32*191d7ec1SSascha Wildnerwork at porting the NetBSD Operating System to the Alpha architectures 33*191d7ec1SSascha Wildner(specifically the AlphaServer 8200 and 8400 platforms). In short, it 34*191d7ec1SSascha Wildnerstarted just as simple single SCSI HBA driver for just the purpose of 35*191d7ec1SSascha Wildnerrunning off a SCSI disk. This work took place starting in January, 1997. 36*191d7ec1SSascha Wildner 37*191d7ec1SSascha WildnerBecause the first implementation was for NetBSD, which runs on a very 38*191d7ec1SSascha Wildnerlarge number of platforms, and because NetBSD supported both systems with 39*191d7ec1SSascha WildnerSBus cards (e.g., Sun SPARC systems) as well as systems with PCI cards, 40*191d7ec1SSascha Wildnerand because the QLogic SCSI cards came in both SBus and PCI versions, the 41*191d7ec1SSascha Wildnerinitial implementation followed the very thoughtful NetBSD design tenet 42*191d7ec1SSascha Wildnerof splitting drivers into what are called MI (for Machine Independent) 43*191d7ec1SSascha Wildnerand MD (Machine Dependent) portions. The original design therefore was 44*191d7ec1SSascha Wildnerfrom the premise that the driver would drive both SBus and PCI card 45*191d7ec1SSascha Wildnervariants. These busses are similar but have quite different constraints, 46*191d7ec1SSascha Wildnerand while the QLogic SBus and PCI cards are very similar, there are some 47*191d7ec1SSascha Wildnersignificant differences. 48*191d7ec1SSascha Wildner 49*191d7ec1SSascha WildnerAfter this initial goal had been met, there began to be some talk about 50*191d7ec1SSascha Wildnerlooking into implementing Fibre Channel mass storage at NAS. At this time 51*191d7ec1SSascha Wildnerthe QLogic 2100 FC/AL HBA was about to become available. After looking at 52*191d7ec1SSascha Wildnerthe way it was designed I concluded that it was so darned close to being 53*191d7ec1SSascha Wildnerjust like the SCSI HBAs that it would be insane to *not* leverage off of 54*191d7ec1SSascha Wildnerthe existing driver. So, we ended up with a driver for NetBSD that drove 55*191d7ec1SSascha WildnerPCI and SBus SCSI cards, and now also drove the QLogic 2100 FC-AL HBA. 56*191d7ec1SSascha Wildner 57*191d7ec1SSascha WildnerAfter this, ports to non-NetBSD platforms became interesting as well. 58*191d7ec1SSascha WildnerThis took the driver out of the interest with NAS and into interested 59*191d7ec1SSascha Wildnersupport from a number of other places. Since the original NetBSD 60*191d7ec1SSascha Wildnerdevelopment, the driver has been ported to FreeBSD, OpenBSD, Linux, 61*191d7ec1SSascha WildnerSolaris, and two proprietary systems. Following from the original MI/MD 62*191d7ec1SSascha Wildnerdesign of NetBSD, a rather successful attempt has been made to keep the 63*191d7ec1SSascha WildnerOperating System Platform differences segregated and to a minimum. 64*191d7ec1SSascha Wildner 65*191d7ec1SSascha WildnerAlong the way, support for the 2200 as well as full fabric and target 66*191d7ec1SSascha Wildnermode support has been added, and 2300 support as well as an FC-IP stack 67*191d7ec1SSascha Wildnerare planned. 68*191d7ec1SSascha Wildner 69*191d7ec1SSascha Wildner3. Driver Design Goals 70*191d7ec1SSascha Wildner 71*191d7ec1SSascha WildnerThe driver has not started out as one normally would do such an effort. 72*191d7ec1SSascha WildnerNormally you design via top-down methodologies and set an intial goal 73*191d7ec1SSascha Wildnerand meet it. This driver has had a design goal that changes from almost 74*191d7ec1SSascha Wildnerthe very first. This has been an extremely peculiar, if not risque, 75*191d7ec1SSascha Wildnerexperience. As a consequence, this section of this document contains 76*191d7ec1SSascha Wildnera bit of "reconstruction after the fact" in that the design goals are 77*191d7ec1SSascha Wildneras I perceive them to be now- not necessarily what they started as. 78*191d7ec1SSascha Wildner 79*191d7ec1SSascha WildnerThe primary design goal now is to have a driver that can run both the 80*191d7ec1SSascha WildnerSCSI and Fibre Channel SCSI prototocols on multiple OS platforms with 81*191d7ec1SSascha Wildneras little OS platform support code as possible. 82*191d7ec1SSascha Wildner 83*191d7ec1SSascha WildnerThe intended support targets for SCSI HBAs is to support the single and 84*191d7ec1SSascha Wildnerdual channel PCI Ultra2 and PCI Ultra3 cards as well as the older PCI 85*191d7ec1SSascha WildnerUltra single channel cards and SBus cards. 86*191d7ec1SSascha Wildner 87*191d7ec1SSascha WildnerThe intended support targets for Fibre Channel HBAs is the 2100, 2200 88*191d7ec1SSascha Wildnerand 2300 PCI cards. 89*191d7ec1SSascha Wildner 90*191d7ec1SSascha WildnerFibre Channel support should include complete fabric and public loop 91*191d7ec1SSascha Wildneras well as private loop and private loop, direct-attach topologies. 92*191d7ec1SSascha WildnerFC-IP support is also a goal. 93*191d7ec1SSascha Wildner 94*191d7ec1SSascha WildnerFor both SCSI and Fibre Channel, simultaneous target/initiator mode support 95*191d7ec1SSascha Wildneris a goal. 96*191d7ec1SSascha Wildner 97*191d7ec1SSascha WildnerPure, raw, performance is not a primary goal of this design. This design, 98*191d7ec1SSascha Wildnerbecause it has a tremendous amount of code common across multiple 99*191d7ec1SSascha Wildnerplatforms, will undoubtedly never be able to beat the performance of a 100*191d7ec1SSascha Wildnerdriver that is specifically designed for a single platform and a single 101*191d7ec1SSascha Wildnercard. However, it is a good strong secondary goal to make the performance 102*191d7ec1SSascha Wildnerpenalties in this design as small as possible. 103*191d7ec1SSascha Wildner 104*191d7ec1SSascha WildnerAnother primary aim, which almost need not be stated, is that the 105*191d7ec1SSascha Wildnerimplementation of platform differences must not clutter up the common 106*191d7ec1SSascha Wildnercode with platform specific defines. Instead, some reasonable layering 107*191d7ec1SSascha Wildnersemantics are defined such that platform specifics can be kept in the 108*191d7ec1SSascha Wildnerplatform specific code. 109*191d7ec1SSascha Wildner 110*191d7ec1SSascha Wildner4. QLogic Hardware Architecture 111*191d7ec1SSascha Wildner 112*191d7ec1SSascha WildnerIn order to make the design of this driver more intelligible, some 113*191d7ec1SSascha Wildnerdescription of the Qlogic hardware architecture is in order. This will 114*191d7ec1SSascha Wildnernot be an exhaustive description of how this card works, but will 115*191d7ec1SSascha Wildnernote enough of the important features so that the driver design is 116*191d7ec1SSascha Wildnerhopefully clearer. 117*191d7ec1SSascha Wildner 118*191d7ec1SSascha Wildner4.1 Basic QLogic hardware 119*191d7ec1SSascha Wildner 120*191d7ec1SSascha WildnerThe QLogic HBA cards all contain a tiny 16-bit RISC-like processor and 121*191d7ec1SSascha Wildnervarying sizes of SRAM. Each card contains a Bus Interface Unit (BIU) 122*191d7ec1SSascha Wildneras appropriate for the host bus (SBus or PCI). The BIUs allow access 123*191d7ec1SSascha Wildnerto a set of dual-ranked 16 bit incoming and outgoing mailbox registers 124*191d7ec1SSascha Wildneras well as access to control registers that control the RISC or access 125*191d7ec1SSascha Wildnerother portions of the card (e.g., Flash BIOS). The term 'dual-ranked' 126*191d7ec1SSascha Wildnermeans that at the same host visible address if you write a mailbox 127*191d7ec1SSascha Wildnerregister, that is a write to an (incoming, to the HBA) mailbox register, 128*191d7ec1SSascha Wildnerwhile a read to the same address reads another (outgoing, to the HBA) 129*191d7ec1SSascha Wildnermailbox register with completely different data. Each HBA also then has 130*191d7ec1SSascha Wildnercore and auxillary logic which either is used to interface to a SCSI bus 131*191d7ec1SSascha Wildner(or to external bus drivers that connect to a SCSI bus), or to connect 132*191d7ec1SSascha Wildnerto a Fibre Channel bus. 133*191d7ec1SSascha Wildner 134*191d7ec1SSascha Wildner4.2 Basic Control Interface 135*191d7ec1SSascha Wildner 136*191d7ec1SSascha WildnerThere are two principle I/O control mechanisms by which the driver 137*191d7ec1SSascha Wildnercommunicates with and controls the QLogic HBA. The first mechanism is to 138*191d7ec1SSascha Wildneruse the incoming mailbox registers to interrupt and issue commands to 139*191d7ec1SSascha Wildnerthe RISC processor (with results usually, but not always, ending up in 140*191d7ec1SSascha Wildnerthe ougtoing mailbox registers). The second mechanism is to establish, 141*191d7ec1SSascha Wildnervia mailbox commands, circular request and response queues in system 142*191d7ec1SSascha Wildnermemory that are then shared between the QLogic and the driver. The 143*191d7ec1SSascha Wildnerrequest queue is used to queue requests (e.g., I/O requests) for the 144*191d7ec1SSascha WildnerQLogic HBA's RISC engine to copy into the HBA memory and process. The 145*191d7ec1SSascha Wildnerresult queue is used by the QLogic HBA's RISC engine to place results of 146*191d7ec1SSascha Wildnerrequests read from the request queue, as well as to place notification 147*191d7ec1SSascha Wildnerof asynchronous events (e.g., incoming commands in target mode). 148*191d7ec1SSascha Wildner 149*191d7ec1SSascha WildnerTo give a bit more precise scale to the preceding description, the QLogic 150*191d7ec1SSascha WildnerHBA has 8 dual-ranked 16 bit mailbox registers, mostly for out-of-band 151*191d7ec1SSascha Wildnercontrol purposes. The QLogic HBA then utilizes a circular request queue 152*191d7ec1SSascha Wildnerof 64 byte fixed size Queue Entries to receive normal initiator mode 153*191d7ec1SSascha WildnerI/O commands (or continue target mode requests). The request queue may 154*191d7ec1SSascha Wildnerbe up to 256 elements for the QLogic 1020 and 1040 chipsets, but may 155*191d7ec1SSascha Wildnerbe quite larger for the QLogic 12X0/12160 SCSI and QLogic 2X00 Fibre 156*191d7ec1SSascha WildnerChannel chipsets. 157*191d7ec1SSascha Wildner 158*191d7ec1SSascha WildnerIn addition to synchronously initiated usage of mailbox commands by 159*191d7ec1SSascha Wildnerthe host system, the QLogic may also deliver asynchronous notifications 160*191d7ec1SSascha Wildnersolely in outgoing mailbox registers. These asynchronous notifications in 161*191d7ec1SSascha Wildnermailboxes may be things like notification of SCSI Bus resets, or that the 162*191d7ec1SSascha WildnerFabric Name server has sent a change notification, or even that a specific 163*191d7ec1SSascha WildnerI/O command completed without error (this is called 'Fast Posting' 164*191d7ec1SSascha Wildnerand saves the QLogic HBA from having to write a response queue entry). 165*191d7ec1SSascha Wildner 166*191d7ec1SSascha WildnerThe QLogic HBA is an interrupting card, and when servicing an interrupt 167*191d7ec1SSascha Wildneryou really only have to check for either a mailbox interrupt or an 168*191d7ec1SSascha Wildnerinterrupt notification that the response queue has an entry to 169*191d7ec1SSascha Wildnerbe dequeued. 170*191d7ec1SSascha Wildner 171*191d7ec1SSascha Wildner4.3 Fibre Channel SCSI out of SCSI 172*191d7ec1SSascha Wildner 173*191d7ec1SSascha WildnerQLogic took the approach in introducing the 2X00 cards to just treat 174*191d7ec1SSascha WildnerFC-AL as a 'fat' SCSI bus (a SCSI bus with more than 15 targets). All 175*191d7ec1SSascha Wildnerof the things that you really need to do with Fibre Channel with respect 176*191d7ec1SSascha Wildnerto providing FC-4 services on top of a Class 3 connection are performed 177*191d7ec1SSascha Wildnerby the RISC engine on the QLogic card itself. This means that from 178*191d7ec1SSascha Wildneran HBA driver point of view, very little needs to change that would 179*191d7ec1SSascha Wildnerdistinguish addressing a Fibre Channel disk from addressing a plain 180*191d7ec1SSascha Wildnerold SCSI disk. 181*191d7ec1SSascha Wildner 182*191d7ec1SSascha WildnerHowever, in the details it's not *quite* that simple. For example, in 183*191d7ec1SSascha Wildnerorder to manage Fabric Connections, the HBA driver has to do explicit 184*191d7ec1SSascha Wildnerbinding of entities it's queried from the name server to specific 'target' 185*191d7ec1SSascha Wildnerids (targets, in this case, being a virtual entity). 186*191d7ec1SSascha Wildner 187*191d7ec1SSascha WildnerStill- the HBA firmware does really nearly all of the tedious management 188*191d7ec1SSascha Wildnerof Fibre Channel login state. The corollary to this sometimes is the 189*191d7ec1SSascha Wildnerlack of ability to say why a particular login connection to a Fibre 190*191d7ec1SSascha WildnerChannel disk is not working well. 191*191d7ec1SSascha Wildner 192*191d7ec1SSascha WildnerThere are clear limits with the QLogic card in managing fabric devices. 193*191d7ec1SSascha WildnerThe QLogic manages local loop devices (LoopID or Target 0..126) itself, 194*191d7ec1SSascha Wildnerbut for the management of fabric devices, it has an absolute limit of 195*191d7ec1SSascha Wildner253 simultaneous connections (256 entries less 3 reserved entries). 196*191d7ec1SSascha Wildner 197*191d7ec1SSascha Wildner5. Driver Architecture 198*191d7ec1SSascha Wildner 199*191d7ec1SSascha Wildner5.1 Driver Assumptions 200*191d7ec1SSascha Wildner 201*191d7ec1SSascha WildnerThe first basic assumption for this driver is that the requirements for 202*191d7ec1SSascha Wildnera SCSI HBA driver for any system is that of a 2 or 3 layer model where 203*191d7ec1SSascha Wildnerthere are SCSI target device drivers (drivers which drive SCSI disks, 204*191d7ec1SSascha WildnerSCSI tapes, and so on), possibly a middle services layer, and a bottom 205*191d7ec1SSascha Wildnerlayer that manages the transport of SCSI CDB's out a SCSI bus (or across 206*191d7ec1SSascha WildnerFibre Channel) to a SCSI device. It's assumed that each SCSI command is 207*191d7ec1SSascha Wildnera separate structure (or pointer to a structure) that contains the SCSI 208*191d7ec1SSascha WildnerCDB and a place to store SCSI Status and SCSI Sense Data. 209*191d7ec1SSascha Wildner 210*191d7ec1SSascha WildnerThis turns out to be a pretty good assumption. All of the Open Source 211*191d7ec1SSascha Wildnersystems (*BSD and Linux) and most of the proprietary systems have this 212*191d7ec1SSascha Wildnerkind of structure. This has been the way to manage SCSI subsystems for 213*191d7ec1SSascha Wildnerat least ten years. 214*191d7ec1SSascha Wildner 215*191d7ec1SSascha WildnerThere are some additional basic assumptions that this driver makes- primarily 216*191d7ec1SSascha Wildnerin the arena of basic simple services like memory zeroing, memory copying, 217*191d7ec1SSascha Wildnerdelay, sleep, microtime functions. It doesn't assume much more than this. 218*191d7ec1SSascha Wildner 219*191d7ec1SSascha Wildner5.2 Overall Driver Architecture 220*191d7ec1SSascha Wildner 221*191d7ec1SSascha WildnerThe driver is split into a core (machine independent) module and platform 222*191d7ec1SSascha Wildnerand bus specific outer modules (machine dependent). 223*191d7ec1SSascha Wildner 224*191d7ec1SSascha WildnerThe core code (in the files isp.c, isp_inline.h, ispvar.h, ispreg.h and 225*191d7ec1SSascha Wildnerispmbox.h) handles: 226*191d7ec1SSascha Wildner 227*191d7ec1SSascha Wildner + Chipset recognition and reset and firmware download (isp_reset) 228*191d7ec1SSascha Wildner + Board Initialization (isp_init) 229*191d7ec1SSascha Wildner + First level interrupt handling (response retrieval) (isp_intr) 230*191d7ec1SSascha Wildner + A SCSI command queueing entry point (isp_start) 231*191d7ec1SSascha Wildner + A set of control services accessed either via local requirements within 232*191d7ec1SSascha Wildner the core module or via an externally visible control entry point 233*191d7ec1SSascha Wildner (isp_control). 234*191d7ec1SSascha Wildner 235*191d7ec1SSascha WildnerThe platform/bus specific modules (and definitions) depend on each 236*191d7ec1SSascha Wildnerplatform, and they provide both definitions and functions for the core 237*191d7ec1SSascha Wildnermodule's use. Generally a platform module set is split into a bus 238*191d7ec1SSascha Wildnerdependent module (where configuration is begun from and bus specific 239*191d7ec1SSascha Wildnersupport functions reside) and relatively thin platform specific layer 240*191d7ec1SSascha Wildnerwhich serves as the interconnect with the rest of this platform's SCSI 241*191d7ec1SSascha Wildnersubsystem. 242*191d7ec1SSascha Wildner 243*191d7ec1SSascha WildnerFor ease of bus specific access issues, a centralized soft state 244*191d7ec1SSascha Wildnerstructure is maintained for each HBA instance (struct ispsoftc). This 245*191d7ec1SSascha Wildnersoft state structure contains a machine/bus dependent vector (mdvec) 246*191d7ec1SSascha Wildnerfor functions that read and write hardware registers, set up DMA for the 247*191d7ec1SSascha Wildnerrequest/response queues and fibre channel scratch area, set up and tear 248*191d7ec1SSascha Wildnerdown DMA mappings for a SCSI command, provide a pointer to firmware to 249*191d7ec1SSascha Wildnerload, and other minor things. 250*191d7ec1SSascha Wildner 251*191d7ec1SSascha WildnerThe machine dependent outer module must provide functional entry points 252*191d7ec1SSascha Wildnerfor the core module: 253*191d7ec1SSascha Wildner 254*191d7ec1SSascha Wildner + A SCSI command completion handoff point (isp_done) 255*191d7ec1SSascha Wildner + An asynchronous event handler (isp_async) 256*191d7ec1SSascha Wildner + A logging/printing function (isp_prt) 257*191d7ec1SSascha Wildner 258*191d7ec1SSascha WildnerThe machine dependent outer module code must also provide a set of 259*191d7ec1SSascha Wildnerabstracting definitions which is what the core module utilizes heavily 260*191d7ec1SSascha Wildnerto do its job. These are discussed in detail in the comments in the 261*191d7ec1SSascha Wildnerfile ispvar.h, but to give a sense of the range of what is required, 262*191d7ec1SSascha Wildnerlet's illustrate two basic classes of these defines. 263*191d7ec1SSascha Wildner 264*191d7ec1SSascha WildnerThe first class are "structure definition/access" class. An 265*191d7ec1SSascha Wildnerexample of these would be: 266*191d7ec1SSascha Wildner 267*191d7ec1SSascha Wildner XS_T Platform SCSI transaction type (i.e., command for HBA) 268*191d7ec1SSascha Wildner .. 269*191d7ec1SSascha Wildner XS_TGT(xs) gets the target from an XS_T 270*191d7ec1SSascha Wildner .. 271*191d7ec1SSascha Wildner XS_TAG_TYPE(xs) which type of tag to use 272*191d7ec1SSascha Wildner .. 273*191d7ec1SSascha Wildner 274*191d7ec1SSascha WildnerThe second class are 'functional' class definitions. Some examples of 275*191d7ec1SSascha Wildnerthis class are: 276*191d7ec1SSascha Wildner 277*191d7ec1SSascha Wildner MEMZERO(dst, src) platform zeroing function 278*191d7ec1SSascha Wildner .. 279*191d7ec1SSascha Wildner MBOX_WAIT_COMPLETE(struct ispsoftc *) wait for mailbox cmd to be done 280*191d7ec1SSascha Wildner 281*191d7ec1SSascha WildnerNote that the former is likely to be simple replacement with bzero or 282*191d7ec1SSascha Wildnermemset on most systems, while the latter could be quite complex. 283*191d7ec1SSascha Wildner 284*191d7ec1SSascha WildnerThis soft state structure also contains different parameter information 285*191d7ec1SSascha Wildnerbased upon whether this is a SCSI HBA or a Fibre Channel HBA (which is 286*191d7ec1SSascha Wildnerfilled in by the code module). 287*191d7ec1SSascha Wildner 288*191d7ec1SSascha WildnerIn order to clear up what is undoubtedly a seeming confusion of 289*191d7ec1SSascha Wildnerinterconnects, a description of the typical flow of code that performs 290*191d7ec1SSascha Wildnerboards initialization and command transactions may help. 291*191d7ec1SSascha Wildner 292*191d7ec1SSascha Wildner5.3 Initialization Code Flow 293*191d7ec1SSascha Wildner 294*191d7ec1SSascha WildnerTypically a bus specific module for a platform (e.g., one that wants 295*191d7ec1SSascha Wildnerto configure a PCI card) is entered via that platform's configuration 296*191d7ec1SSascha Wildnermethods. If this module recognizes a card and can utilize or construct the 297*191d7ec1SSascha Wildnerspace for the HBA instance softc, it does so, and initializes the machine 298*191d7ec1SSascha Wildnerdependent vector as well as any other platform specific information that 299*191d7ec1SSascha Wildnercan be hidden in or associated with this structure. 300*191d7ec1SSascha Wildner 301*191d7ec1SSascha WildnerConfiguration at this point usually involves mapping in board registers 302*191d7ec1SSascha Wildnerand registering an interrupt. It's quite possible that the core module's 303*191d7ec1SSascha Wildnerisp_intr function is adequate to be the interrupt entry point, but often 304*191d7ec1SSascha Wildnerit's more useful have a bus specific wrapper module that calls isp_intr. 305*191d7ec1SSascha Wildner 306*191d7ec1SSascha WildnerAfter mapping and interrupt registry is done, isp_reset is called. 307*191d7ec1SSascha WildnerPart of the isp_reset call may cause callbacks out to the bus dependent 308*191d7ec1SSascha Wildnermodule to perform allocation and/or mapping of Request and Response 309*191d7ec1SSascha Wildnerqueues (as well as a Fibre Channel scratch area if this is a Fibre 310*191d7ec1SSascha WildnerChannel HBA). The reason this is considered 'bus dependent' is that 311*191d7ec1SSascha Wildneronly the bus dependent module may have the information that says how 312*191d7ec1SSascha Wildnerone could perform I/O mapping and dependent (e.g., on a Solaris system) 313*191d7ec1SSascha Wildneron the Request and Reponse queues. Another callback can enable the *use* 314*191d7ec1SSascha Wildnerof interrupts should this platform be able to finish configuration in 315*191d7ec1SSascha Wildnerinterrupt driven mode. 316*191d7ec1SSascha Wildner 317*191d7ec1SSascha WildnerIf isp_reset is successful at resetting the QLogic chipset and downloading 318*191d7ec1SSascha Wildnernew firmware (if available) and setting it running, isp_init is called. If 319*191d7ec1SSascha Wildnerisp_init is successful in doing initial board setups (including reading 320*191d7ec1SSascha WildnerNVRAM from the QLogic card), then this bus specicic module will call the 321*191d7ec1SSascha Wildnerplatform dependent module that takes the appropriate steps to 'register' 322*191d7ec1SSascha Wildnerthis HBA with this platform's SCSI subsystem. Examining either the 323*191d7ec1SSascha WildnerOpenBSD or the NetBSD isp_pci.c or isp_sbus.c files may assist the reader 324*191d7ec1SSascha Wildnerhere in clarifying some of this. 325*191d7ec1SSascha Wildner 326*191d7ec1SSascha Wildner5.4 Initiator Mode Command Code Flow 327*191d7ec1SSascha Wildner 328*191d7ec1SSascha WildnerA succesful execution of isp_init will lead to the driver 'registering' 329*191d7ec1SSascha Wildneritself with this platform's SCSI subsystem. One assumed action for this 330*191d7ec1SSascha Wildneris the registry of a function that the SCSI subsystem for this platform 331*191d7ec1SSascha Wildnerwill call when it has a SCSI command to run. 332*191d7ec1SSascha Wildner 333*191d7ec1SSascha WildnerThe platform specific module function that receives this will do whatever 334*191d7ec1SSascha Wildnerit needs to to prepare this command for execution in the core module. This 335*191d7ec1SSascha Wildnersounds vague, but it's also very flexible. In principle, this could be 336*191d7ec1SSascha Wildnera complete marshalling/demarshalling of this platform's SCSI command 337*191d7ec1SSascha Wildnerstructure (should it be impossible to represent in an XS_T). In addition, 338*191d7ec1SSascha Wildnerthis function can also block commands from running (if, e.g., Fibre 339*191d7ec1SSascha WildnerChannel loop state would preclude successful starting of the command). 340*191d7ec1SSascha Wildner 341*191d7ec1SSascha WildnerWhen it's ready to do so, the function isp_start is called with this 342*191d7ec1SSascha Wildnercommand. This core module tries to allocate request queue space for 343*191d7ec1SSascha Wildnerthis command. It also calls through the machine dependent vector 344*191d7ec1SSascha Wildnerfunction to make sure any DMA mapping for this command is done. 345*191d7ec1SSascha Wildner 346*191d7ec1SSascha WildnerNow, DMA mapping here is possibly a misnomer, as more than just 347*191d7ec1SSascha WildnerDMA mapping can be done in this bus dependent function. This is 348*191d7ec1SSascha Wildneralso the place where any endian byte-swizzling will be done. At any 349*191d7ec1SSascha Wildnerrate, this function is called last because the process of establishing 350*191d7ec1SSascha WildnerDMA addresses for any command may in fact consume more Request Queue 351*191d7ec1SSascha Wildnerentries than there are currently available. If the mapping and other 352*191d7ec1SSascha Wildnerfunctions are successful, the QLogic mailbox inbox pointer register 353*191d7ec1SSascha Wildneris updated to indicate to the QLogic that it has a new request to 354*191d7ec1SSascha Wildnerread. 355*191d7ec1SSascha Wildner 356*191d7ec1SSascha WildnerIf this function is unsuccessful, policy as to what to do at this point is 357*191d7ec1SSascha Wildnerleft to the machine dependent platform function which called isp_start. In 358*191d7ec1SSascha Wildnersome platforms, temporary resource shortages can be handled by the main 359*191d7ec1SSascha WildnerSCSI subsystem. In other platforms, the machine dependent code has to 360*191d7ec1SSascha Wildnerhandle this. 361*191d7ec1SSascha Wildner 362*191d7ec1SSascha WildnerIn order to keep track of commands that are in progress, the soft state 363*191d7ec1SSascha Wildnerstructure contains an array of 'handles' that are associated with each 364*191d7ec1SSascha Wildneractive command. When you send a command to the QLogic firmware, a portion 365*191d7ec1SSascha Wildnerof the Request Queue entry can contain a non-zero handle identifier so 366*191d7ec1SSascha Wildnerthat at a later point in time in reading either a Response Queue entry 367*191d7ec1SSascha Wildneror from a Fast Posting mailbox completion interrupt, you can take this 368*191d7ec1SSascha Wildnerhandle to find the command you were waiting on. It should be noted that 369*191d7ec1SSascha Wildnerthis is probably one of the most dangerous areas of this driver. Corrupted 370*191d7ec1SSascha Wildnerhandles will lead to system panics. 371*191d7ec1SSascha Wildner 372*191d7ec1SSascha WildnerAt some later point in time an interrupt will occur. Eventually, 373*191d7ec1SSascha Wildnerisp_intr will be called. This core module will determine what the cause 374*191d7ec1SSascha Wildnerof the interrupt is, and if it is for a completing command. That is, 375*191d7ec1SSascha Wildnerit'll determine the handle and fetch the pointer to the command out of 376*191d7ec1SSascha Wildnerstorage within the soft state structure. Skipping over a lot of details, 377*191d7ec1SSascha Wildnerthe machine dependent code supplied function isp_done is called with the 378*191d7ec1SSascha Wildnerpointer to the completing command. This would then be the glue layer that 379*191d7ec1SSascha Wildnerinforms the SCSI subsystem for this platform that a command is complete. 380*191d7ec1SSascha Wildner 381*191d7ec1SSascha Wildner5.5 Asynchronous Events 382*191d7ec1SSascha Wildner 383*191d7ec1SSascha WildnerInterrupts occur for events other than commands (mailbox or request queue 384*191d7ec1SSascha Wildnerstarted commands) completing. These are called Asynchronous Mailbox 385*191d7ec1SSascha Wildnerinterrupts. When some external event causes the SCSI bus to be reset, 386*191d7ec1SSascha Wildneror when a Fibre Channel loop changes state (e.g., a LIP is observed), 387*191d7ec1SSascha Wildnerthis generates such an asynchronous event. 388*191d7ec1SSascha Wildner 389*191d7ec1SSascha WildnerEach platform module has to provide an isp_async entry point that will 390*191d7ec1SSascha Wildnerhandle a set of these. This isp_async entry point also handles things 391*191d7ec1SSascha Wildnerwhich aren't properly async events but are simply natural outgrowths 392*191d7ec1SSascha Wildnerof code flow for another core function (see discussion on fabric device 393*191d7ec1SSascha Wildnermanagement below). 394*191d7ec1SSascha Wildner 395*191d7ec1SSascha Wildner5.6 Target Mode Code Flow 396*191d7ec1SSascha Wildner 397*191d7ec1SSascha WildnerThis section could use a lot of expansion, but this covers the basics. 398*191d7ec1SSascha Wildner 399*191d7ec1SSascha WildnerThe QLogic cards, when operating in target mode, follow a code flow that is 400*191d7ec1SSascha Wildneressentially the inverse of that for intiator mode describe above. In this 401*191d7ec1SSascha Wildnerscenario, an interrupt occurs, and present on the Response Queue is a 402*191d7ec1SSascha Wildnerqueue entry element defining a new command arriving from an initiator. 403*191d7ec1SSascha Wildner 404*191d7ec1SSascha WildnerThis is passed to possibly external target mode handler. This driver 405*191d7ec1SSascha Wildnerprovides some handling for this in a core module, but also leaves 406*191d7ec1SSascha Wildnerthings open enough that a completely different target mode handler 407*191d7ec1SSascha Wildnermay accept this incoming queue entry. 408*191d7ec1SSascha Wildner 409*191d7ec1SSascha WildnerThe external target mode handler then turns around forms up a response 410*191d7ec1SSascha Wildnerto this 'response' that just arrived which is then placed on the Request 411*191d7ec1SSascha WildnerQueue and handled very much like an initiator mode command (i.e., calling 412*191d7ec1SSascha Wildnerthe bus dependent DMA mapping function). If this entry completes the 413*191d7ec1SSascha Wildnercommand, no more need occur. But often this handles only part of the 414*191d7ec1SSascha Wildnerrequested command, so the QLogic firmware will rewrite the response 415*191d7ec1SSascha Wildnerto the initial 'response' again onto the Response Queue, whereupon the 416*191d7ec1SSascha Wildnertarget mode handler will respond to that, and so on until the command 417*191d7ec1SSascha Wildneris completely handled. 418*191d7ec1SSascha Wildner 419*191d7ec1SSascha WildnerBecause almost no platform provides basic SCSI Subsystem target mode 420*191d7ec1SSascha Wildnersupport, this design has been left extremely open ended, and as such 421*191d7ec1SSascha Wildnerit's a bit hard to describe in more detail than this. 422*191d7ec1SSascha Wildner 423*191d7ec1SSascha Wildner5.7 Locking Assumptions 424*191d7ec1SSascha Wildner 425*191d7ec1SSascha WildnerThe observant reader by now is likely to have asked the question, "but what 426*191d7ec1SSascha Wildnerabout locking? Or interrupt masking" by now. 427*191d7ec1SSascha Wildner 428*191d7ec1SSascha WildnerThe basic assumption about this is that the core module does not know 429*191d7ec1SSascha Wildneranything directly about locking or interrupt masking. It may assume that 430*191d7ec1SSascha Wildnerupon entry (e.g., via isp_start, isp_control, isp_intr) that appropriate 431*191d7ec1SSascha Wildnerlocking and interrupt masking has been done. 432*191d7ec1SSascha Wildner 433*191d7ec1SSascha WildnerThe platform dependent code may also therefore assume that if it is 434*191d7ec1SSascha Wildnercalled (e.g., isp_done or isp_async) that any locking or masking that 435*191d7ec1SSascha Wildnerwas in place upon the entry to the core module is still there. It is up 436*191d7ec1SSascha Wildnerto the platform dependent code to worry about avoiding any lock nesting 437*191d7ec1SSascha Wildnerissues. As an example of this, the Linux implementation simply queues 438*191d7ec1SSascha Wildnerup commands completed via the callout to isp_done, which it then pushes 439*191d7ec1SSascha Wildnerout to the SCSI subsystem after a return from it's calling isp_intr is 440*191d7ec1SSascha Wildnerexecuted (and locks dropped appropriately, as well as avoidance of deep 441*191d7ec1SSascha Wildnerinterrupt stacks). 442*191d7ec1SSascha Wildner 443*191d7ec1SSascha WildnerRecent changes in the design have now eased what had been an original 444*191d7ec1SSascha Wildnerrequirement that the while in the core module no locks or interrupt 445*191d7ec1SSascha Wildnermasking could be dropped. It's now up to each platform to figure out how 446*191d7ec1SSascha Wildnerto implement this. This is principally used in the execution of mailbox 447*191d7ec1SSascha Wildnercommands (which are principally used for Loop and Fabric management via 448*191d7ec1SSascha Wildnerthe isp_control function). 449*191d7ec1SSascha Wildner 450*191d7ec1SSascha Wildner5.8 SCSI Specifics 451*191d7ec1SSascha Wildner 452*191d7ec1SSascha WildnerThe driver core or platform dependent architecture issues that are specific 453*191d7ec1SSascha Wildnerto SCSI are few. There is a basic assumption that the QLogic firmware 454*191d7ec1SSascha Wildnersupported Automatic Request sense will work- there is no particular provision 455*191d7ec1SSascha Wildnerfor disabling it's usage on a per-command basis. 456*191d7ec1SSascha Wildner 457*191d7ec1SSascha Wildner5.9 Fibre Channel Specifics 458*191d7ec1SSascha Wildner 459*191d7ec1SSascha WildnerFibre Channel presents an interesting challenge here. The QLogic firmware 460*191d7ec1SSascha Wildnerarchitecture for dealing with Fibre Channel as just a 'fat' SCSI bus 461*191d7ec1SSascha Wildneris fine on the face of it, but there are some subtle and not so subtle 462*191d7ec1SSascha Wildnerproblems here. 463*191d7ec1SSascha Wildner 464*191d7ec1SSascha Wildner5.9.1 Firmware State 465*191d7ec1SSascha Wildner 466*191d7ec1SSascha WildnerPart of the initialization (isp_init) for Fibre Channel HBAs involves 467*191d7ec1SSascha Wildnersending a command (Initialize Control Block) that establishes Node 468*191d7ec1SSascha Wildnerand Port WWNs as well as topology preferences. After this occurs, 469*191d7ec1SSascha Wildnerthe QLogic firmware tries to traverese through serveral states: 470*191d7ec1SSascha Wildner 471*191d7ec1SSascha Wildner FW_CONFIG_WAIT 472*191d7ec1SSascha Wildner FW_WAIT_AL_PA 473*191d7ec1SSascha Wildner FW_WAIT_LOGIN 474*191d7ec1SSascha Wildner FW_READY 475*191d7ec1SSascha Wildner FW_LOSS_OF_SYNC 476*191d7ec1SSascha Wildner FW_ERROR 477*191d7ec1SSascha Wildner FW_REINIT 478*191d7ec1SSascha Wildner FW_NON_PART 479*191d7ec1SSascha Wildner 480*191d7ec1SSascha WildnerIt starts with FW_CONFIG_WAIT, attempts to get an AL_PA (if on an FC-AL 481*191d7ec1SSascha Wildnerloop instead of being connected as an N-port), waits to log into all 482*191d7ec1SSascha WildnerFC-AL loop entities and then hopefully transitions to FW_READY state. 483*191d7ec1SSascha Wildner 484*191d7ec1SSascha WildnerClearly, no command should be attempted prior to FW_READY state is 485*191d7ec1SSascha Wildnerachieved. The core internal function isp_fclink_test (reachable via 486*191d7ec1SSascha Wildnerisp_control with the ISPCTL_FCLINK_TEST function code). This function 487*191d7ec1SSascha Wildneralso determines connection topology (i.e., whether we're attached to a 488*191d7ec1SSascha Wildnerfabric or not). 489*191d7ec1SSascha Wildner 490*191d7ec1SSascha Wildner5.9.2. Loop State Transitions- From Nil to Ready 491*191d7ec1SSascha Wildner 492*191d7ec1SSascha WildnerOnce the firmware has transitioned to a ready state, then the state of the 493*191d7ec1SSascha Wildnerconnection to either arbitrated loop or to a fabric has to be ascertained, 494*191d7ec1SSascha Wildnerand the identity of all loop members (and fabric members validated). 495*191d7ec1SSascha Wildner 496*191d7ec1SSascha WildnerThis can be very complicated, and it isn't made easy in that the QLogic 497*191d7ec1SSascha Wildnerfirmware manages PLOGI and PRLI to devices that are on a local loop, but 498*191d7ec1SSascha Wildnerit is the driver that must manage PLOGI/PRLI with devices on the fabric. 499*191d7ec1SSascha Wildner 500*191d7ec1SSascha WildnerIn order to manage this state an eight level staging of current "Loop" 501*191d7ec1SSascha Wildner(where "Loop" is taken to mean FC-AL or N- or F-port connections) states 502*191d7ec1SSascha Wildnerin the following ascending order: 503*191d7ec1SSascha Wildner 504*191d7ec1SSascha Wildner LOOP_NIL 505*191d7ec1SSascha Wildner LOOP_LIP_RCVD 506*191d7ec1SSascha Wildner LOOP_PDB_RCVD 507*191d7ec1SSascha Wildner LOOP_SCANNING_FABRIC 508*191d7ec1SSascha Wildner LOOP_FSCAN_DONE 509*191d7ec1SSascha Wildner LOOP_SCANNING_LOOP 510*191d7ec1SSascha Wildner LOOP_LSCAN_DONE 511*191d7ec1SSascha Wildner LOOP_SYNCING_PDB 512*191d7ec1SSascha Wildner LOOP_READY 513*191d7ec1SSascha Wildner 514*191d7ec1SSascha WildnerWhen the core code initializes the QLogic firmware, it sets the loop 515*191d7ec1SSascha Wildnerstate to LOOP_NIL. The first 'LIP Received' asynchronous event sets state 516*191d7ec1SSascha Wildnerto LOOP_LIP_RCVD. This should be followed by a "Port Database Changed" 517*191d7ec1SSascha Wildnerasynchronous event which will set the state to LOOP_PDB_RCVD. Each of 518*191d7ec1SSascha Wildnerthese states, when entered, causes an isp_async event call to the 519*191d7ec1SSascha Wildnermachine dependent layers with the ISPASYNC_CHANGE_NOTIFY code. 520*191d7ec1SSascha Wildner 521*191d7ec1SSascha WildnerAfter the state of LOOP_PDB_RCVD is reached, the internal core function 522*191d7ec1SSascha Wildnerisp_scan_fabric (reachable via isp_control(..ISPCTL_SCAN_FABRIC)) will, 523*191d7ec1SSascha Wildnerif the connection is to a fabric, use Simple Name Server mailbox mediated 524*191d7ec1SSascha Wildnercommands to dump the entire fabric contents. For each new entity, an 525*191d7ec1SSascha Wildnerisp_async event will be generated that says a Fabric device has arrived 526*191d7ec1SSascha Wildner(ISPASYNC_FABRIC_DEV). The function that isp_async must perform in this 527*191d7ec1SSascha Wildnerstep is to insert possibly remove devices that it wants to have the 528*191d7ec1SSascha WildnerQLogic firmware log into (at LOOP_SYNCING_PDB state level)). 529*191d7ec1SSascha Wildner 530*191d7ec1SSascha WildnerAfter this has occurred, the state LOOP_FSCAN_DONE is set, and then the 531*191d7ec1SSascha Wildnerinternal function isp_scan_loop (isp_control(...ISPCTL_SCAN_LOOP)) can 532*191d7ec1SSascha Wildnerbe called which will then scan for any local (FC-AL) entries by asking 533*191d7ec1SSascha Wildnerfor each possible local loop id the QLogic firmware for a Port Database 534*191d7ec1SSascha Wildnerentry. It's at this level some entries cached locally are purged 535*191d7ec1SSascha Wildneror shifting loopids are managed (see section 5.9.4). 536*191d7ec1SSascha Wildner 537*191d7ec1SSascha WildnerThe final step after this is to call the internal function isp_pdb_sync 538*191d7ec1SSascha Wildner(isp_control(..ISPCTL_PDB_SYNC)). The purpose of this function is to 539*191d7ec1SSascha Wildnerthen perform the PLOGI/PRLI functions for fabric devices. The next state 540*191d7ec1SSascha Wildnerentered after this is LOOP_READY, which means that the driver is ready 541*191d7ec1SSascha Wildnerto process commands to send to Fibre Channel devices. 542*191d7ec1SSascha Wildner 543*191d7ec1SSascha Wildner5.9.3 Fibre Channel variants of Initiator Mode Code Flow 544*191d7ec1SSascha Wildner 545*191d7ec1SSascha WildnerThe code flow in isp_start for Fibre Channel devices is the same as it is 546*191d7ec1SSascha Wildnerfor SCSI devices, but with a notable exception. 547*191d7ec1SSascha Wildner 548*191d7ec1SSascha WildnerMaintained within the fibre channel specific portion of the driver soft 549*191d7ec1SSascha Wildnerstate structure is a distillation of the existing population of both 550*191d7ec1SSascha Wildnerlocal loop and fabric devices. Because Loop IDs can shift on a local 551*191d7ec1SSascha Wildnerloop but we wish to retain a 'constant' Target ID (see 5.9.4), this 552*191d7ec1SSascha Wildneris indexed directly via the Target ID for the command (XS_TGT(xs)). 553*191d7ec1SSascha Wildner 554*191d7ec1SSascha WildnerIf there is a valid entry for this Target ID, the command is started 555*191d7ec1SSascha Wildner(with the stored 'Loop ID'). If not the command is completed with 556*191d7ec1SSascha Wildnerthe error that is just like a SCSI Selection Timeout error. 557*191d7ec1SSascha Wildner 558*191d7ec1SSascha WildnerThis code is currently somewhat in transition. Some platforms to 559*191d7ec1SSascha Wildnerdo firmware and loop state management (as described above) at this 560*191d7ec1SSascha Wildnerpoint. Other platforms manage this from the machine dependent layers. The 561*191d7ec1SSascha Wildnerimportant function to watch in this respect is isp_fc_runstate (in 562*191d7ec1SSascha Wildnerisp_inline.h). 563*191d7ec1SSascha Wildner 564*191d7ec1SSascha Wildner5.9.4 "Target" in Fibre Channel is a fixed virtual construct 565*191d7ec1SSascha Wildner 566*191d7ec1SSascha WildnerVery few systems can cope with the notion that "Target" for a disk 567*191d7ec1SSascha Wildnerdevice can change while you're using it. But one of the properties of 568*191d7ec1SSascha Wildnerfor arbitrated loop is that the physical bus address for a loop member 569*191d7ec1SSascha Wildner(the AL_PA) can change depending on when and how things are inserted in 570*191d7ec1SSascha Wildnerthe loop. 571*191d7ec1SSascha Wildner 572*191d7ec1SSascha WildnerTo illustrate this, let's take an example. Let's say you start with a 573*191d7ec1SSascha Wildnerloop that has 5 disks in it. At boot time, the system will likely find 574*191d7ec1SSascha Wildnerthem and see them in this order: 575*191d7ec1SSascha Wildner 576*191d7ec1SSascha Wildnerdisk# Loop ID Target ID 577*191d7ec1SSascha Wildnerdisk0 0 0 578*191d7ec1SSascha Wildnerdisk1 1 1 579*191d7ec1SSascha Wildnerdisk2 2 2 580*191d7ec1SSascha Wildnerdisk3 3 3 581*191d7ec1SSascha Wildnerdisk4 4 4 582*191d7ec1SSascha Wildner 583*191d7ec1SSascha WildnerThe driver uses 'Loop ID' when it forms requests to send a comamnd to 584*191d7ec1SSascha Wildnereach disk. However, it reports to NetBSD that things exist as 'Target 585*191d7ec1SSascha WildnerID'. As you can see here, there is perfect correspondence between disk, 586*191d7ec1SSascha WildnerLoop ID and Target ID. 587*191d7ec1SSascha Wildner 588*191d7ec1SSascha WildnerLet's say you add a new disk between disk2 and disk3 while things are 589*191d7ec1SSascha Wildnerrunning. You don't really often see this, but you *could* see this where 590*191d7ec1SSascha Wildnerthe loop has to renegotiate, and you end up with: 591*191d7ec1SSascha Wildner 592*191d7ec1SSascha Wildnerdisk# Loop ID Target ID 593*191d7ec1SSascha Wildnerdisk0 0 0 594*191d7ec1SSascha Wildnerdisk1 1 1 595*191d7ec1SSascha Wildnerdisk2 2 2 596*191d7ec1SSascha WildnerdiskN 3 ? 597*191d7ec1SSascha Wildnerdisk3 4 ? 598*191d7ec1SSascha Wildnerdisk4 5 ? 599*191d7ec1SSascha Wildner 600*191d7ec1SSascha WildnerClearly, you don't want disk3 and disk4's "Target ID" to change while you're 601*191d7ec1SSascha Wildnerrunning since currently mounted filesystems will get trashed. 602*191d7ec1SSascha Wildner 603*191d7ec1SSascha WildnerWhat the driver is supposed to do (this is the function of isp_scan_loop), 604*191d7ec1SSascha Wildneris regenerate things such that the following then occurs: 605*191d7ec1SSascha Wildner 606*191d7ec1SSascha Wildnerdisk# Loop ID Target ID 607*191d7ec1SSascha Wildnerdisk0 0 0 608*191d7ec1SSascha Wildnerdisk1 1 1 609*191d7ec1SSascha Wildnerdisk2 2 2 610*191d7ec1SSascha WildnerdiskN 3 5 611*191d7ec1SSascha Wildnerdisk3 4 3 612*191d7ec1SSascha Wildnerdisk4 5 4 613*191d7ec1SSascha Wildner 614*191d7ec1SSascha WildnerSo, "Target" is a virtual entity that is maintained while you're running. 615*191d7ec1SSascha Wildner 616*191d7ec1SSascha Wildner6. Glossary 617*191d7ec1SSascha Wildner 618*191d7ec1SSascha WildnerHBA - Host Bus Adapter 619*191d7ec1SSascha Wildner 620*191d7ec1SSascha WildnerSCSI - Small Computer 621*191d7ec1SSascha Wildner 622*191d7ec1SSascha Wildner7. References 623*191d7ec1SSascha Wildner 624*191d7ec1SSascha WildnerVarious URLs of interest: 625*191d7ec1SSascha Wildner 626*191d7ec1SSascha Wildnerhttp://www.netbsd.org - NetBSD's Web Page 627*191d7ec1SSascha Wildnerhttp://www.openbsd.org - OpenBSD's Web Page 628*191d7ec1SSascha Wildnerhttp://www.freebsd.org - FreeBSD's Web Page 629*191d7ec1SSascha Wildner 630*191d7ec1SSascha Wildnerhttp://www.t10.org - ANSI SCSI Commitee's Web Page 631*191d7ec1SSascha Wildner (SCSI Specs) 632*191d7ec1SSascha Wildnerhttp://www.t11.org - NCITS Device Interface Web Page 633*191d7ec1SSascha Wildner (Fibre Channel Specs) 634