Annotation of Gnu-Mach/linux/src/drivers/scsi/AM53C974.c, revision 1.1

1.1     ! root        1: #include <linux/module.h>
        !             2: 
        !             3: #include <linux/config.h>
        !             4: #include <linux/delay.h>
        !             5: #include <linux/signal.h>
        !             6: #include <linux/sched.h>
        !             7: #include <linux/errno.h>
        !             8: #include <linux/bios32.h>
        !             9: #include <linux/pci.h>
        !            10: #include <linux/string.h>
        !            11: #include <linux/blk.h>
        !            12: 
        !            13: #include <asm/io.h>
        !            14: #include <asm/system.h>
        !            15: 
        !            16: #include "scsi.h"
        !            17: #include "hosts.h"
        !            18: #include "AM53C974.h"
        !            19: #include "constants.h"
        !            20: #include "sd.h"
        !            21: 
        !            22: /* AM53/79C974 (PCscsi) driver release 0.5
        !            23:  *
        !            24:  * The architecture and much of the code of this device
        !            25:  * driver was originally developed by Drew Eckhardt for
        !            26:  * the NCR5380. The following copyrights apply:
        !            27:  *  For the architecture and all pieces of code which can also be found 
        !            28:  *    in the NCR5380 device driver:
        !            29:  *   Copyright 1993, Drew Eckhardt
        !            30:  *     Visionary Computing 
        !            31:  *     (Unix and Linux consulting and custom programming)
        !            32:  *     [email protected]
        !            33:  *     +1 (303) 666-5836
        !            34:  *
        !            35:  *  The AM53C974_nobios_detect code was originally developed by
        !            36:  *   Robin Cutshaw ([email protected]) and is used here in a 
        !            37:  *   slightly modified form.
        !            38:  *
        !            39:  *  For the remaining code:
        !            40:  *    Copyright 1994, D. Frieauff
        !            41:  *    EMail: [email protected]
        !            42:  *    Phone: x49-7545-8-2256 , x49-7541-42305
        !            43:  */
        !            44: 
        !            45: /*
        !            46:  * $Log: AM53C974.c,v $
        !            47:  * Revision 1.1  1999/04/26 05:53:47  tb
        !            48:  * 1998-11-30  OKUJI Yoshinori  <[email protected]>
        !            49:  *
        !            50:  *     Clean up linux emulation code to make it architecture-independent
        !            51:  *     as much as possible.
        !            52:  *
        !            53:  *     * linux: Renamed from linuxdev.
        !            54:  *     * Makefile.in (objfiles): Add linux.o instead of linuxdev.o.
        !            55:  *     (MAKE): New variable. Used for the linux.o target.
        !            56:  *     * configure.in: Add AC_CHECK_TOOL(MAKE, make).
        !            57:  *     * i386/i386/spl.h: Include <i386/ipl.h>, for compatibility with
        !            58:  *     OSF Mach 3.0. Suggested by Elgin Lee <[email protected]>.
        !            59:  *     * linux/src: Renamed from linux/linux.
        !            60:  *     * linux/dev: Renamed from linux/mach.
        !            61:  *     * linux/Drivers.in (AC_INIT): Use dev/include/linux/autoconf.h,
        !            62:  *     instead of mach/include/linux/autoconf.h.
        !            63:  *     * Makefile.in (all): Target ../linux.o instead of ../linuxdev.o.
        !            64:  *     * linux/dev/drivers/block/genhd.c: Include <machine/spl.h> instead
        !            65:  *     of <i386/ipl.h>.
        !            66:  *     * linux/dev/drivers/net/auto_irq.c: Remove unneeded header files,
        !            67:  *     <i386/ipl.h> and <i386/pic.h>.
        !            68:  *     * linux/dev/init/main.c: Many i386-dependent codes moved to ...
        !            69:  *     * linux/dev/arch/i386/irq.c: ... here.
        !            70:  *     * linux/dev/arch/i386/setup.c: New file.
        !            71:  *     * linux/dev/arch/i386/linux_emul.h: Likewise.
        !            72:  *     * linux/dev/arch/i386/glue/timer.c: Merged into sched.c.
        !            73:  *     * linux/dev/arch/i386/glue/sched.c: Include <machine/spl.h> instead
        !            74:  *     of <i386/ipl.h>, and moved to ...
        !            75:  *     * linux/dev/kernel/sched.c: ... here.
        !            76:  *     * linux/dev/arch/i386/glue/block.c: Include <machine/spl.h> and
        !            77:  *     <linux_emul.h>, instead of i386-dependent header files, and
        !            78:  *     moved to ...
        !            79:  *     * linux/dev/glue/blocl.c: ... here.
        !            80:  *     * linux/dev/arch/i386/glue/net.c: Include <machine/spl.h> and
        !            81:  *     <linux_emul.h>, instead of i386-dependent header files, and
        !            82:  *     moved to ...
        !            83:  *     * linux/dev/glue/net.c: ... here.
        !            84:  *     * linux/dev/arch/i386/glue/misc.c: Remove `x86' and moved to ...
        !            85:  *     * linux/dev/glue/misc.c: ... here.
        !            86:  *     * linux/dev/arch/i386/glue/kmem.c: Moved to ...
        !            87:  *     * linux/dev/glue/kmem.c: ... here.
        !            88:  *
        !            89:  */
        !            90: 
        !            91: #ifdef AM53C974_DEBUG
        !            92:  #define DEB(x) x
        !            93:  #ifdef AM53C974_DEBUG_KEYWAIT
        !            94:    #define KEYWAIT() AM53C974_keywait()
        !            95:   #else
        !            96:    #define KEYWAIT()
        !            97:   #endif
        !            98:  #ifdef AM53C974_DEBUG_INIT
        !            99:    #define DEB_INIT(x) x
        !           100:   #else
        !           101:    #define DEB_INIT(x)
        !           102:   #endif
        !           103:  #ifdef AM53C974_DEBUG_MSG
        !           104:    #define DEB_MSG(x) x
        !           105:   #else
        !           106:    #define DEB_MSG(x)
        !           107:   #endif
        !           108:  #ifdef AM53C974_DEB_RESEL
        !           109:    #define DEB_RESEL(x) x
        !           110:   #else
        !           111:    #define DEB_RESEL(x)
        !           112:   #endif
        !           113:  #ifdef AM53C974_DEBUG_QUEUE
        !           114:   #define DEB_QUEUE(x) x
        !           115:   #define LIST(x,y) {printk("LINE:%d   Adding %p to %p\n", __LINE__, (void*)(x), (void*)(y)); if ((x)==(y)) udelay(5); }
        !           116:   #define REMOVE(w,x,y,z) {printk("LINE:%d   Removing: %p->%p  %p->%p \n", __LINE__, (void*)(w), (void*)(x), (void*)(y), (void*)(z)); if ((x)==(y)) udelay(5); }
        !           117:  #else
        !           118:   #define DEB_QUEUE(x)
        !           119:   #define LIST(x,y)
        !           120:   #define REMOVE(w,x,y,z)
        !           121:  #endif
        !           122:  #ifdef AM53C974_DEBUG_INFO
        !           123:    #define DEB_INFO(x) x
        !           124:   #else
        !           125:    #define DEB_INFO(x)
        !           126:   #endif
        !           127:  #ifdef AM53C974_DEBUG_LINKED
        !           128:    #define DEB_LINKED(x) x
        !           129:   #else
        !           130:    #define DEB_LINKED(x)
        !           131:   #endif
        !           132:  #ifdef AM53C974_DEBUG_INTR
        !           133:    #define DEB_INTR(x) x
        !           134:   #else
        !           135:    #define DEB_INTR(x)
        !           136:   #endif
        !           137: #else
        !           138:  #define DEB_INIT(x)
        !           139:  #define DEB(x)
        !           140:  #define DEB_QUEUE(x)
        !           141:  #define LIST(x,y)
        !           142:  #define REMOVE(w,x,y,z)
        !           143:  #define DEB_INFO(x)
        !           144:  #define DEB_LINKED(x)
        !           145:  #define DEB_INTR(x)
        !           146:  #define DEB_MSG(x)
        !           147:  #define DEB_RESEL(x)
        !           148:  #define KEYWAIT()
        !           149: #endif
        !           150:  #ifdef AM53C974_DEBUG_ABORT
        !           151:    #define DEB_ABORT(x) x
        !           152:   #else
        !           153:    #define DEB_ABORT(x)
        !           154:   #endif
        !           155: 
        !           156: #ifdef VERBOSE_AM53C974_DEBUG
        !           157: #define VDEB(x) x
        !           158: #else
        !           159: #define VDEB(x)
        !           160: #endif
        !           161: 
        !           162: #define INSIDE(x,l,h) ( ((x) >= (l)) && ((x) <= (h)) )
        !           163: 
        !           164: #ifdef AM53C974_DEBUG
        !           165: static void AM53C974_print_pci(struct Scsi_Host *instance);
        !           166: static void AM53C974_print_phase(struct Scsi_Host *instance);
        !           167: static void AM53C974_print_queues(struct Scsi_Host *instance);
        !           168: #endif /* AM53C974_DEBUG */
        !           169: static void AM53C974_print(struct Scsi_Host *instance);
        !           170: static void AM53C974_keywait(void);
        !           171: static int AM53C974_bios_detect(Scsi_Host_Template *tpnt);
        !           172: static int AM53C974_nobios_detect(Scsi_Host_Template *tpnt);
        !           173: static int AM53C974_init(Scsi_Host_Template *tpnt, pci_config_t pci_config);
        !           174: static void AM53C974_config_after_reset(struct Scsi_Host *instance);
        !           175: static __inline__ void initialize_SCp(Scsi_Cmnd *cmd);
        !           176: static __inline__ void run_main(void);
        !           177: static void AM53C974_main (void);
        !           178: static void AM53C974_intr(int irq, void *dev_id, struct pt_regs *regs);
        !           179: static void AM53C974_intr_disconnect(struct Scsi_Host *instance); 
        !           180: static int AM53C974_sync_neg(struct Scsi_Host *instance, int target, unsigned char *msg);
        !           181: static __inline__ void AM53C974_set_async(struct Scsi_Host *instance, int target);
        !           182: static __inline__ void AM53C974_set_sync(struct Scsi_Host *instance, int target);
        !           183: static void AM53C974_information_transfer(struct Scsi_Host *instance, 
        !           184:                                           unsigned char statreg, unsigned char isreg,
        !           185:                                           unsigned char instreg, unsigned char cfifo,
        !           186:                                           unsigned char dmastatus);
        !           187: static int AM53C974_message(struct Scsi_Host *instance, Scsi_Cmnd *cmd, unsigned char msg);
        !           188: static void AM53C974_select(struct Scsi_Host *instance, Scsi_Cmnd *cmd, int tag);
        !           189: static void AM53C974_intr_reselect(struct Scsi_Host *instance, unsigned char statreg);
        !           190: static  __inline__ void AM53C974_transfer_dma(struct Scsi_Host *instance, short dir,
        !           191:                                               unsigned long length, char *data);
        !           192: static void AM53C974_dma_blast(struct Scsi_Host *instance, unsigned char dmastatus, 
        !           193:                                unsigned char statreg);
        !           194: static void AM53C974_intr_bus_reset(struct Scsi_Host *instance);
        !           195: 
        !           196: static struct Scsi_Host *first_instance = NULL;
        !           197: static Scsi_Host_Template *the_template = NULL;
        !           198: static struct Scsi_Host *first_host = NULL;    /* Head of list of AMD boards */
        !           199: static volatile int main_running = 0;
        !           200: static int commandline_current = 0;
        !           201: override_t overrides[7] = { {-1, 0, 0, 0}, };   /* LILO overrides */
        !           202: 
        !           203: struct proc_dir_entry proc_scsi_am53c974 = {
        !           204:        PROC_SCSI_AM53C974, 8, "am53c974",
        !           205:        S_IFDIR | S_IRUGO | S_IXUGO, 2
        !           206: };
        !           207: 
        !           208: #ifdef AM53C974_DEBUG
        !           209: static int deb_stop = 1;
        !           210: 
        !           211: /**************************************************************************
        !           212:  * Function : void AM53C974_print_pci(struct Scsi_Host *instance)
        !           213:  *
        !           214:  * Purpose : dump the PCI registers for debugging purposes
        !           215:  *
        !           216:  * Input : instance - which AM53C974
        !           217:  **************************************************************************/
        !           218: static void AM53C974_print_pci(struct Scsi_Host *instance)
        !           219: {
        !           220: int            i;
        !           221: unsigned short vendor_id, device_id, command, status, scratch[8];
        !           222: unsigned long  class_revision, base; 
        !           223: unsigned char  irq, cache_line_size, latency_timer, header_type;
        !           224: 
        !           225: AM53C974_PCIREG_OPEN();
        !           226: 
        !           227: for (i = 0; i < 8; i++) *(scratch + i) = AM53C974_PCIREG_READ_WORD(instance, PCI_SCRATCH_REG_0 + 2*i);
        !           228: vendor_id = AM53C974_PCIREG_READ_WORD(instance, PCI_VENDOR_ID);
        !           229: device_id = AM53C974_PCIREG_READ_WORD(instance, PCI_DEVICE_ID);
        !           230: command   = AM53C974_PCIREG_READ_WORD(instance, PCI_COMMAND);
        !           231: status    = AM53C974_PCIREG_READ_WORD(instance, PCI_STATUS);
        !           232: class_revision = AM53C974_PCIREG_READ_DWORD(instance, PCI_CLASS_REVISION);
        !           233: cache_line_size = AM53C974_PCIREG_READ_BYTE(instance, PCI_CACHE_LINE_SIZE);
        !           234: latency_timer = AM53C974_PCIREG_READ_BYTE(instance, PCI_LATENCY_TIMER);
        !           235: header_type = AM53C974_PCIREG_READ_BYTE(instance, PCI_HEADER_TYPE);
        !           236: base = AM53C974_PCIREG_READ_DWORD(instance, PCI_BASE_ADDRESS_0);
        !           237: irq = AM53C974_PCIREG_READ_BYTE(instance, PCI_INTERRUPT_LINE);
        !           238: 
        !           239: AM53C974_PCIREG_CLOSE();
        !           240: 
        !           241: 
        !           242: printk("------------- start of PCI register dump -------------\n");
        !           243: printk("PCI_VENDOR_ID:       0x%x\n", vendor_id);
        !           244: printk("PCI_DEVICE_ID:       0x%x\n", device_id);
        !           245: printk("PCI_COMMAND:         0x%x\n", command);
        !           246: printk("PCI_STATUS:          0x%x\n", status);
        !           247: printk("PCI_CLASS_REVISION:  0x%lx\n", class_revision);
        !           248: printk("PCI_CACHE_LINE_SIZE: 0x%x\n", cache_line_size);
        !           249: printk("PCI_LATENCY_TIMER:   0x%x\n", latency_timer);
        !           250: printk("PCI_HEADER_TYPE:     0x%x\n", header_type);
        !           251: printk("PCI_BASE_ADDRESS_0:  0x%lx\n", base);
        !           252: printk("PCI_INTERRUPT_LINE:  %d\n", irq);
        !           253: for (i = 0; i < 8; i++) printk("PCI_SCRATCH_%d:       0x%x\n", i, scratch[i]);
        !           254: printk("------------- end of PCI register dump -------------\n\n");
        !           255: }
        !           256: 
        !           257: static struct {
        !           258:     unsigned char value;
        !           259:     char *name;
        !           260: } phases[] = {
        !           261: {PHASE_DATAOUT, "DATAOUT"}, {PHASE_DATAIN, "DATAIN"}, {PHASE_CMDOUT, "CMDOUT"},
        !           262: {PHASE_STATIN, "STATIN"}, {PHASE_MSGOUT, "MSGOUT"}, {PHASE_MSGIN, "MSGIN"},
        !           263: {PHASE_RES_0, "RESERVED 0"}, {PHASE_RES_1, "RESERVED 1"}};
        !           264: 
        !           265: /************************************************************************** 
        !           266:  * Function : void AM53C974_print_phase(struct Scsi_Host *instance)
        !           267:  *
        !           268:  * Purpose : print the current SCSI phase for debugging purposes
        !           269:  *
        !           270:  * Input : instance - which AM53C974
        !           271:  **************************************************************************/
        !           272: static void AM53C974_print_phase(struct Scsi_Host *instance)
        !           273: {
        !           274: AM53C974_local_declare();
        !           275: unsigned char statreg, latched;
        !           276: int           i;
        !           277: AM53C974_setio(instance);
        !           278: 
        !           279: latched = (AM53C974_read_8(CNTLREG2)) & CNTLREG2_ENF;
        !           280: statreg = AM53C974_read_8(STATREG);
        !           281: for (i = 0; (phases[i].value != PHASE_RES_1) && 
        !           282:      (phases[i].value != (statreg & STATREG_PHASE)); ++i); 
        !           283: if (latched)
        !           284:    printk("scsi%d : phase %s, latched at end of last command\n", instance->host_no, phases[i].name);
        !           285:   else
        !           286:    printk("scsi%d : phase %s, real time\n", instance->host_no, phases[i].name);
        !           287: }
        !           288: 
        !           289: /**************************************************************************
        !           290:  * Function : void AM53C974_print_queues(struct Scsi_Host *instance)
        !           291:  *
        !           292:  * Purpose : print commands in the various queues
        !           293:  *
        !           294:  * Inputs : instance - which AM53C974
        !           295:  **************************************************************************/
        !           296: static void AM53C974_print_queues(struct Scsi_Host *instance)
        !           297: {
        !           298: struct AM53C974_hostdata *hostdata = (struct AM53C974_hostdata *)instance->hostdata;
        !           299: Scsi_Cmnd *ptr;
        !           300: 
        !           301: printk("AM53C974: coroutine is%s running.\n", main_running ? "" : "n't");
        !           302:     
        !           303: cli();
        !           304:     
        !           305: if (!hostdata->connected) {
        !           306:    printk ("scsi%d: no currently connected command\n", instance->host_no); } 
        !           307:   else {
        !           308:    print_Scsi_Cmnd ((Scsi_Cmnd *)hostdata->connected); }
        !           309: if (!hostdata->sel_cmd) {
        !           310:    printk ("scsi%d: no currently arbitrating command\n", instance->host_no); } 
        !           311:   else {
        !           312:    print_Scsi_Cmnd ((Scsi_Cmnd *)hostdata->sel_cmd); }
        !           313: 
        !           314: printk ("scsi%d: issue_queue ", instance->host_no);
        !           315: if (!hostdata->issue_queue)
        !           316:    printk("empty\n");
        !           317:   else {
        !           318:    printk(":\n");
        !           319:    for (ptr = (Scsi_Cmnd *)hostdata->issue_queue; ptr; ptr = (Scsi_Cmnd *)ptr->host_scribble) 
        !           320:        print_Scsi_Cmnd (ptr); }
        !           321: 
        !           322: printk ("scsi%d: disconnected_queue ", instance->host_no);
        !           323: if (!hostdata->disconnected_queue)
        !           324:    printk("empty\n");
        !           325:   else {
        !           326:    printk(":\n");
        !           327:    for (ptr = (Scsi_Cmnd *) hostdata->disconnected_queue; ptr; ptr = (Scsi_Cmnd *)ptr->host_scribble) 
        !           328:        print_Scsi_Cmnd (ptr); }
        !           329:     
        !           330: sti();
        !           331: }
        !           332: 
        !           333: #endif /* AM53C974_DEBUG */
        !           334: 
        !           335: /**************************************************************************
        !           336:  * Function : void AM53C974_print(struct Scsi_Host *instance)
        !           337:  *
        !           338:  * Purpose : dump the chip registers for debugging purposes
        !           339:  *
        !           340:  * Input : instance - which AM53C974
        !           341:  **************************************************************************/
        !           342: static void AM53C974_print(struct Scsi_Host *instance)
        !           343: {
        !           344: AM53C974_local_declare();
        !           345: unsigned long ctcreg, dmastc, dmaspa, dmawbc, dmawac;
        !           346: unsigned char cmdreg, statreg, isreg, cfireg, cntlreg[4], dmacmd, dmastatus;
        !           347: AM53C974_setio(instance);
        !           348: 
        !           349: cli();
        !           350: ctcreg = AM53C974_read_8(CTCHREG) << 16;
        !           351: ctcreg |= AM53C974_read_8(CTCMREG) << 8;
        !           352: ctcreg |= AM53C974_read_8(CTCLREG);
        !           353: cmdreg = AM53C974_read_8(CMDREG);
        !           354: statreg = AM53C974_read_8(STATREG);
        !           355: isreg = AM53C974_read_8(ISREG);
        !           356: cfireg = AM53C974_read_8(CFIREG);
        !           357: cntlreg[0] = AM53C974_read_8(CNTLREG1);
        !           358: cntlreg[1] = AM53C974_read_8(CNTLREG2);
        !           359: cntlreg[2] = AM53C974_read_8(CNTLREG3);
        !           360: cntlreg[3] = AM53C974_read_8(CNTLREG4);
        !           361: dmacmd = AM53C974_read_8(DMACMD);
        !           362: dmastc = AM53C974_read_32(DMASTC);
        !           363: dmaspa = AM53C974_read_32(DMASPA);
        !           364: dmawbc = AM53C974_read_32(DMAWBC);
        !           365: dmawac = AM53C974_read_32(DMAWAC);
        !           366: dmastatus = AM53C974_read_8(DMASTATUS);
        !           367: sti();
        !           368: 
        !           369: printk("AM53C974 register dump:\n");
        !           370: printk("IO base: 0x%04lx; CTCREG: 0x%04lx; CMDREG: 0x%02x; STATREG: 0x%02x; ISREG: 0x%02x\n",
        !           371:        io_port, ctcreg, cmdreg, statreg, isreg);
        !           372: printk("CFIREG: 0x%02x; CNTLREG1-4: 0x%02x; 0x%02x; 0x%02x; 0x%02x\n",
        !           373:         cfireg, cntlreg[0], cntlreg[1], cntlreg[2], cntlreg[3]);
        !           374: printk("DMACMD: 0x%02x; DMASTC: 0x%04lx; DMASPA: 0x%04lx\n", dmacmd, dmastc, dmaspa);
        !           375: printk("DMAWBC: 0x%04lx; DMAWAC: 0x%04lx; DMASTATUS: 0x%02x\n", dmawbc, dmawac, dmastatus);
        !           376: printk("---------------------------------------------------------\n");
        !           377: }
        !           378: 
        !           379: /**************************************************************************
        !           380: * Function : void AM53C974_keywait(void)
        !           381: *
        !           382: * Purpose : wait until a key is pressed, if it was the 'r' key leave singlestep mode;
        !           383: *           this function is used for debugging only
        !           384: *
        !           385: * Input : none
        !           386: **************************************************************************/
        !           387: static void AM53C974_keywait(void)
        !           388: {
        !           389: #ifdef AM53C974_DEBUG
        !           390: int key;
        !           391: 
        !           392: if (!deb_stop) return;
        !           393: #endif
        !           394: 
        !           395: cli();
        !           396: while ((inb_p(0x64) & 0x01) != 0x01) ;
        !           397: #ifdef AM53C974_DEBUG
        !           398: key = inb(0x60);
        !           399: if (key == 0x93) deb_stop = 0;  /* don't stop if 'r' was pressed */
        !           400: #endif
        !           401: sti();
        !           402: }
        !           403: 
        !           404: /**************************************************************************
        !           405: * Function : AM53C974_setup(char *str, int *ints)
        !           406: *
        !           407: * Purpose : LILO command line initialization of the overrides array,
        !           408: * 
        !           409: * Inputs : str - unused, ints - array of integer parameters with ints[0]
        !           410: *          equal to the number of ints.
        !           411: *
        !           412: * NOTE : this function needs to be declared as an external function
        !           413: *         in init/main.c and included there in the bootsetups list
        !           414: ***************************************************************************/
        !           415: void AM53C974_setup(char *str, int *ints)
        !           416: {
        !           417: if (ints[0] < 4) 
        !           418:    printk("AM53C974_setup: wrong number of parameters;\n correct syntax is: AM53C974=host-scsi-id, target-scsi-id, max-rate, max-offset\n");
        !           419:   else {
        !           420:    if (commandline_current < (sizeof(overrides) / sizeof(override_t))) {
        !           421:       if ((ints[1] < 0) || (ints[1] > 7) ||
        !           422:           (ints[2] < 0) || (ints[2] > 7) ||
        !           423:           (ints[1] == ints[2]) ||
        !           424:           (ints[3] < (DEF_CLK / MAX_PERIOD)) || (ints[3] > (DEF_CLK / MIN_PERIOD)) ||
        !           425:           (ints[4] < 0) || (ints[4] > MAX_OFFSET))
        !           426:          printk("AM53C974_setup: illegal parameter\n");
        !           427:         else {
        !           428:          overrides[commandline_current].host_scsi_id = ints[1];
        !           429:          overrides[commandline_current].target_scsi_id = ints[2];
        !           430:          overrides[commandline_current].max_rate = ints[3];
        !           431:          overrides[commandline_current].max_offset = ints[4];
        !           432:          commandline_current++; }
        !           433:       }
        !           434:      else
        !           435:       printk("AM53C974_setup: too many overrides\n");
        !           436:    }
        !           437: }
        !           438: 
        !           439: #if defined (CONFIG_PCI)
        !           440: /**************************************************************************
        !           441: * Function : int AM53C974_bios_detect(Scsi_Host_Template *tpnt)
        !           442: *
        !           443: * Purpose : detects and initializes AM53C974 SCSI chips with PCI Bios
        !           444: *
        !           445: * Inputs : tpnt - host template
        !           446: * 
        !           447: * Returns : number of host adapters detected
        !           448: **************************************************************************/
        !           449: int AM53C974_bios_detect(Scsi_Host_Template *tpnt)
        !           450: {
        !           451: int count = 0;        /* number of boards detected */
        !           452: int pci_index;
        !           453: pci_config_t pci_config;
        !           454: 
        !           455: for (pci_index = 0; pci_index <= 16; ++pci_index) {
        !           456:     unsigned char pci_bus, pci_device_fn;
        !           457:     if (pcibios_find_device(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_SCSI, pci_index, &pci_bus, &pci_device_fn) != 0)
        !           458:        break;
        !           459: 
        !           460:     pcibios_read_config_word(pci_bus, pci_device_fn, PCI_VENDOR_ID, &pci_config._vendor);
        !           461:     pcibios_read_config_word(pci_bus, pci_device_fn, PCI_DEVICE_ID, &pci_config._device);
        !           462:     pcibios_read_config_word(pci_bus, pci_device_fn, PCI_COMMAND, &pci_config._command);
        !           463:     pcibios_read_config_word(pci_bus, pci_device_fn, PCI_STATUS, &pci_config._status);
        !           464:     pcibios_read_config_dword(pci_bus, pci_device_fn, PCI_CLASS_REVISION, &pci_config._class_revision);
        !           465:     pcibios_read_config_byte(pci_bus, pci_device_fn, PCI_CACHE_LINE_SIZE, &pci_config._cache_line_size);
        !           466:     pcibios_read_config_byte(pci_bus, pci_device_fn, PCI_LATENCY_TIMER, &pci_config._latency_timer);
        !           467:     pcibios_read_config_byte(pci_bus, pci_device_fn, PCI_HEADER_TYPE, &pci_config._header_type);
        !           468:     pcibios_read_config_byte(pci_bus, pci_device_fn, PCI_BIST, &pci_config._bist);
        !           469:     pcibios_read_config_dword(pci_bus, pci_device_fn, PCI_BASE_ADDRESS_0, &pci_config._base0);
        !           470:     pcibios_read_config_dword(pci_bus, pci_device_fn, PCI_BASE_ADDRESS_1, &pci_config._base1);
        !           471:     pcibios_read_config_dword(pci_bus, pci_device_fn, PCI_BASE_ADDRESS_2, &pci_config._base2);
        !           472:     pcibios_read_config_dword(pci_bus, pci_device_fn, PCI_BASE_ADDRESS_3, &pci_config._base3);
        !           473:     pcibios_read_config_dword(pci_bus, pci_device_fn, PCI_BASE_ADDRESS_4, &pci_config._base4);
        !           474:     pcibios_read_config_dword(pci_bus, pci_device_fn, PCI_BASE_ADDRESS_5, &pci_config._base5);
        !           475:     pcibios_read_config_dword(pci_bus, pci_device_fn, PCI_ROM_ADDRESS, &pci_config._baserom);
        !           476:     pcibios_read_config_byte(pci_bus, pci_device_fn, PCI_INTERRUPT_LINE, &pci_config._int_line);
        !           477:     pcibios_read_config_byte(pci_bus, pci_device_fn, PCI_INTERRUPT_PIN, &pci_config._int_pin);
        !           478:     pcibios_read_config_byte(pci_bus, pci_device_fn, PCI_MIN_GNT, &pci_config._min_gnt);
        !           479:     pcibios_read_config_byte(pci_bus, pci_device_fn, PCI_MAX_LAT, &pci_config._max_lat);
        !           480:     pci_config._pcibus = 0xFFFFFFFF;
        !           481:     pci_config._cardnum = 0xFFFFFFFF;
        !           482:  
        !           483:     /* check whether device is I/O mapped -- should be */
        !           484:     if (!(pci_config._command & PCI_COMMAND_IO)) continue;
        !           485: 
        !           486:     /* PCI Spec 2.1 states that it is either the driver's or the PCI card's responsibility
        !           487:        to set the PCI Master Enable Bit if needed. 
        !           488:        (from Mark Stockton <[email protected]>) */
        !           489:     if (!(pci_config._command & PCI_COMMAND_MASTER)) {
        !           490:        pci_config._command |= PCI_COMMAND_MASTER;
        !           491:        printk("PCI Master Bit has not been set. Setting...\n");
        !           492:        pcibios_write_config_word(pci_bus, pci_device_fn, PCI_COMMAND, pci_config._command); }
        !           493: 
        !           494:     /* everything seems OK now, so initialize */
        !           495:     if (AM53C974_init(tpnt, pci_config)) count++ ;
        !           496:     }
        !           497: return (count);
        !           498: }
        !           499: #endif
        !           500: 
        !           501: /**************************************************************************
        !           502: * Function : int AM53C974_nobios_detect(Scsi_Host_Template *tpnt)
        !           503: *
        !           504: * Purpose : detects and initializes AM53C974 SCSI chips using PCI config 2 
        !           505: *
        !           506: * Inputs : tpnt - host template
        !           507: * 
        !           508: * Returns : number of host adapters detected
        !           509: *
        !           510: * NOTE : This code assumes the controller on PCI bus 0.
        !           511: *
        !           512: * Origin: Robin Cutshaw ([email protected])
        !           513: **************************************************************************/
        !           514: int AM53C974_nobios_detect(Scsi_Host_Template *tpnt)
        !           515: {
        !           516: int          count = 0;                /* number of boards detected */
        !           517: pci_config_t pci_config;
        !           518: 
        !           519: /* first try PCI config method 1 */
        !           520: for (pci_config._pcibus = 0; pci_config._pcibus < 0x10; pci_config._pcibus++) {
        !           521:     for (pci_config._cardnum = 0; pci_config._cardnum < 0x20; pci_config._cardnum++) {
        !           522:         unsigned long config_cmd;
        !           523:        config_cmd = 0x80000000 | (pci_config._pcibus<<16) | (pci_config._cardnum<<11);
        !           524: 
        !           525:         outl(config_cmd, 0xCF8);         /* ioreg 0 */
        !           526:         pci_config._device_vendor = inl(0xCFC);
        !           527: 
        !           528:         if ((pci_config._vendor == PCI_VENDOR_ID_AMD) && (pci_config._device == PCI_DEVICE_ID_AMD_SCSI)) {
        !           529:            outl(config_cmd | PCI_COMMAND, 0xCF8); pci_config._status_command  = inl(0xCFC);
        !           530:            outl(config_cmd | PCI_CLASS_REVISION, 0xCF8); pci_config._class_revision = inl(0xCFC);
        !           531:            outl(config_cmd | PCI_CACHE_LINE_SIZE, 0xCF8); pci_config._bist_header_latency_cache = inl(0xCFC);
        !           532:            outl(config_cmd | PCI_BASE_ADDRESS_0, 0xCF8); pci_config._base0 = inl(0xCFC);
        !           533:            outl(config_cmd | PCI_BASE_ADDRESS_1, 0xCF8); pci_config._base1 = inl(0xCFC);
        !           534:            outl(config_cmd | PCI_BASE_ADDRESS_2, 0xCF8); pci_config._base2 = inl(0xCFC);
        !           535:            outl(config_cmd | PCI_BASE_ADDRESS_3, 0xCF8); pci_config._base3 = inl(0xCFC);
        !           536:            outl(config_cmd | PCI_BASE_ADDRESS_4, 0xCF8); pci_config._base4 = inl(0xCFC);
        !           537:            outl(config_cmd | PCI_BASE_ADDRESS_5, 0xCF8); pci_config._base5 = inl(0xCFC);
        !           538:            outl(config_cmd | PCI_ROM_ADDRESS, 0xCF8); pci_config._baserom = inl(0xCFC);
        !           539:            outl(config_cmd | PCI_INTERRUPT_LINE, 0xCF8); pci_config._max_min_ipin_iline = inl(0xCFC);
        !           540: 
        !           541:            /* check whether device is I/O mapped -- should be */
        !           542:            if (!(pci_config._command & PCI_COMMAND_IO)) continue;
        !           543: 
        !           544:            /* PCI Spec 2.1 states that it is either the driver's or the PCI card's responsibility
        !           545:               to set the PCI Master Enable Bit if needed. 
        !           546:               From Mark Stockton <[email protected]> */
        !           547:            if (!(pci_config._command & PCI_COMMAND_MASTER)) {
        !           548:               pci_config._command |= PCI_COMMAND_MASTER;
        !           549:               printk("Config 1; PCI Master Bit has not been set. Setting...\n");
        !           550:               outl(config_cmd | PCI_COMMAND, 0xCF8); outw(pci_config._command, 0xCFC); }
        !           551: 
        !           552:            /* everything seems OK now, so initialize */
        !           553:            if (AM53C974_init(tpnt, pci_config)) count++ ;
        !           554:            }
        !           555:         }
        !           556:     }
        !           557: outb(0, 0xCF8); /* is this really necessary? */
        !           558: 
        !           559: /* try PCI config method 2, if no device was detected by method 1 */
        !           560: if (!count) {
        !           561:    AM53C974_PCIREG_OPEN();
        !           562: 
        !           563:    pci_config._pcibus = 0xFFFFFFFF;
        !           564:    pci_config._cardnum = 0xFFFFFFFF;
        !           565: 
        !           566:    for (pci_config._ioaddr = 0xC000; pci_config._ioaddr < 0xD000; pci_config._ioaddr += 0x0100) {
        !           567:        pci_config._device_vendor = inl(pci_config._ioaddr);
        !           568: 
        !           569:        if ((pci_config._vendor == PCI_VENDOR_ID_AMD) && (pci_config._device == PCI_DEVICE_ID_AMD_SCSI)) {
        !           570:           pci_config._status_command = inl(pci_config._ioaddr + PCI_COMMAND);
        !           571:           pci_config._class_revision = inl(pci_config._ioaddr + PCI_CLASS_REVISION);
        !           572:           pci_config._bist_header_latency_cache = inl(pci_config._ioaddr + PCI_CACHE_LINE_SIZE);
        !           573:           pci_config._base0 = inl(pci_config._ioaddr + PCI_BASE_ADDRESS_0);
        !           574:           pci_config._base1 = inl(pci_config._ioaddr + PCI_BASE_ADDRESS_1);
        !           575:           pci_config._base2 = inl(pci_config._ioaddr + PCI_BASE_ADDRESS_2);
        !           576:           pci_config._base3 = inl(pci_config._ioaddr + PCI_BASE_ADDRESS_3);
        !           577:           pci_config._base4 = inl(pci_config._ioaddr + PCI_BASE_ADDRESS_4);
        !           578:           pci_config._base5 = inl(pci_config._ioaddr + PCI_BASE_ADDRESS_5);
        !           579:           pci_config._baserom = inl(pci_config._ioaddr + PCI_ROM_ADDRESS);
        !           580:           pci_config._max_min_ipin_iline = inl(pci_config._ioaddr + PCI_INTERRUPT_LINE);
        !           581: 
        !           582:           /* check whether device is I/O mapped -- should be */
        !           583:           if (!(pci_config._command & PCI_COMMAND_IO)) continue;
        !           584: 
        !           585:           /* PCI Spec 2.1 states that it is either the driver's or the PCI card's responsibility
        !           586:              to set the PCI Master Enable Bit if needed.
        !           587:              From Mark Stockton <[email protected]> */
        !           588:           if (!(pci_config._command & PCI_COMMAND_MASTER)) {
        !           589:               pci_config._command |= PCI_COMMAND_MASTER;
        !           590:               printk("Config 2; PCI Master Bit has not been set. Setting...\n");
        !           591:               outw(pci_config._command, pci_config._ioaddr + PCI_COMMAND); }
        !           592: 
        !           593:           /* everything seems OK now, so initialize */
        !           594:           if (AM53C974_init(tpnt, pci_config)) count++ ;
        !           595:           }
        !           596:        }
        !           597:    AM53C974_PCIREG_CLOSE();
        !           598:    }
        !           599: 
        !           600: return(count);
        !           601: }
        !           602: 
        !           603: /**************************************************************************
        !           604: * Function : int AM53C974_detect(Scsi_Host_Template *tpnt)
        !           605: *
        !           606: * Purpose : detects and initializes AM53C974 SCSI chips
        !           607: *
        !           608: * Inputs : tpnt - host template
        !           609: * 
        !           610: * Returns : number of host adapters detected
        !           611: **************************************************************************/
        !           612: int AM53C974_detect(Scsi_Host_Template *tpnt)
        !           613: {
        !           614: int count;        /* number of boards detected */
        !           615: 
        !           616: tpnt->proc_dir = &proc_scsi_am53c974;
        !           617: 
        !           618: #if defined (CONFIG_PCI)
        !           619: if (pcibios_present())
        !           620:    count = AM53C974_bios_detect(tpnt);
        !           621:   else
        !           622: #endif
        !           623: count = AM53C974_nobios_detect(tpnt);
        !           624: return (count);
        !           625: }
        !           626: 
        !           627: /**************************************************************************
        !           628: * Function : int AM53C974_init(Scsi_Host_Template *tpnt, pci_config_t pci_config)
        !           629: *
        !           630: * Purpose : initializes instance and corresponding AM53/79C974 chip,
        !           631: *
        !           632: * Inputs : tpnt - template, pci_config - PCI configuration,
        !           633: * 
        !           634: * Returns : 1 on success, 0 on failure.
        !           635: * 
        !           636: * NOTE: If no override for the controller's SCSI id is given and AM53C974_SCSI_ID 
        !           637: *       is not defined we assume that the SCSI address of this controller is correctly
        !           638: *       set up by the BIOS (as reflected by contents of register CNTLREG1).
        !           639: *       This is the only BIOS assistance we need.
        !           640: **************************************************************************/
        !           641: static int AM53C974_init(Scsi_Host_Template *tpnt, pci_config_t pci_config)
        !           642: {
        !           643: AM53C974_local_declare();
        !           644: int                      i, j;
        !           645: struct Scsi_Host         *instance, *search;
        !           646: struct AM53C974_hostdata *hostdata;
        !           647: 
        !           648: #ifdef AM53C974_OPTION_DEBUG_PROBE_ONLY
        !           649:    printk ("AM53C974: probe only enabled, aborting initialization\n");
        !           650:    return 0;
        !           651: #endif
        !           652: 
        !           653: instance = scsi_register(tpnt, sizeof(struct AM53C974_hostdata));
        !           654: hostdata = (struct AM53C974_hostdata *)instance->hostdata;
        !           655: instance->base = NULL;
        !           656: instance->io_port = pci_config._base0 & (pci_config._base0 & 0x1 ? 
        !           657:                                          0xFFFFFFFC : 0xFFFFFFF0);
        !           658: instance->irq = pci_config._int_line;
        !           659: instance->dma_channel = -1;
        !           660: AM53C974_setio(instance);
        !           661: 
        !           662: #ifdef AM53C974_SCSI_ID
        !           663: instance->this_id = AM53C974_SCSI_ID;
        !           664: AM53C974_write_8(CNTLREG1, instance->this_id & CNTLREG1_SID);
        !           665: #else
        !           666: instance->this_id = AM53C974_read_8(CNTLREG1) & CNTLREG1_SID;
        !           667: if (instance->this_id != 7) 
        !           668:    printk("scsi%d: WARNING: unusual hostadapter SCSI id %d; please verify!\n", 
        !           669:           instance->host_no, instance->this_id);
        !           670: #endif
        !           671: 
        !           672: for (i = 0; i < sizeof(hostdata->msgout); i++) {
        !           673:     hostdata->msgout[i] = NOP;
        !           674:     hostdata->last_message[i] = NOP; }
        !           675: for (i = 0; i < 8; i++) {
        !           676:     hostdata->busy[i] = 0;
        !           677:     hostdata->sync_per[i] = DEF_STP;
        !           678:     hostdata->sync_off[i] = 0;
        !           679:     hostdata->sync_neg[i] = 0;
        !           680:     hostdata->sync_en[i] = DEFAULT_SYNC_NEGOTIATION_ENABLED;
        !           681:     hostdata->max_rate[i] = DEFAULT_RATE;
        !           682:     hostdata->max_offset[i] = DEFAULT_SYNC_OFFSET; }
        !           683: 
        !           684: /* overwrite defaults by LILO overrides */
        !           685: for (i = 0; i < commandline_current; i++) {
        !           686:     if (overrides[i].host_scsi_id == instance->this_id) {
        !           687:        j = overrides[i].target_scsi_id;
        !           688:        hostdata->sync_en[j] = 1;
        !           689:        hostdata->max_rate[j] = overrides[i].max_rate;
        !           690:        hostdata->max_offset[j] = overrides[i].max_offset; 
        !           691:        }
        !           692:     }
        !           693: 
        !           694: hostdata->sel_cmd = NULL;
        !           695: hostdata->connected = NULL;
        !           696: hostdata->issue_queue = NULL;
        !           697: hostdata->disconnected_queue = NULL;
        !           698: hostdata->in_reset = 0;
        !           699: hostdata->aborted = 0;
        !           700: hostdata->selecting = 0;
        !           701: hostdata->disconnecting = 0;
        !           702: hostdata->dma_busy = 0;
        !           703: 
        !           704: /* Set up an interrupt handler if we aren't already sharing an IRQ with another board */
        !           705: for (search = first_host; 
        !           706:      search && ( ((the_template != NULL) && (search->hostt != the_template)) || 
        !           707:                  (search->irq != instance->irq) || (search == instance) );
        !           708:      search = search->next);
        !           709: if (!search) {
        !           710:    if (request_irq(instance->irq, AM53C974_intr, SA_INTERRUPT, "AM53C974", NULL)) {
        !           711:       printk("scsi%d: IRQ%d not free, detaching\n", instance->host_no, instance->irq);
        !           712:       scsi_unregister(instance);
        !           713:       return 0; } 
        !           714:    }
        !           715:   else {
        !           716:    printk("scsi%d: using interrupt handler previously installed for scsi%d\n",
        !           717:          instance->host_no, search->host_no); }
        !           718: 
        !           719: if (!the_template) {
        !           720:    the_template = instance->hostt;
        !           721:    first_instance = instance; }
        !           722: 
        !           723: /* do hard reset */
        !           724: AM53C974_write_8(CMDREG, CMDREG_RDEV);     /* reset device */
        !           725: udelay(5);
        !           726: AM53C974_write_8(CMDREG, CMDREG_NOP);
        !           727: AM53C974_write_8(CNTLREG1, CNTLREG1_DISR | instance->this_id); 
        !           728: AM53C974_write_8(CMDREG, CMDREG_RBUS);     /* reset SCSI bus */
        !           729: udelay(10);
        !           730: AM53C974_config_after_reset(instance);
        !           731: udelay(500000);
        !           732: return(1);
        !           733: }
        !           734: 
        !           735: /*********************************************************************
        !           736: * Function : AM53C974_config_after_reset(struct Scsi_Host *instance) *
        !           737: *                                                                    *
        !           738: * Purpose : initializes chip registers after reset                   *
        !           739: *                                                                    *
        !           740: * Inputs : instance - which AM53C974                                 *
        !           741: *                                                                    *
        !           742: * Returns : nothing                                                  *
        !           743: **********************************************************************/
        !           744: static void AM53C974_config_after_reset(struct Scsi_Host *instance)
        !           745: {
        !           746: AM53C974_local_declare(); 
        !           747: AM53C974_setio(instance);
        !           748: 
        !           749: /* clear SCSI FIFO */
        !           750: AM53C974_write_8(CMDREG, CMDREG_CFIFO);
        !           751: 
        !           752: /* configure device */
        !           753: AM53C974_write_8(STIMREG, DEF_SCSI_TIMEOUT);
        !           754: AM53C974_write_8(STPREG, DEF_STP & STPREG_STP);
        !           755: AM53C974_write_8(SOFREG, (DEF_SOF_RAD<<6) | (DEF_SOF_RAA<<4));
        !           756: AM53C974_write_8(CLKFREG, DEF_CLKF & CLKFREG_MASK);
        !           757: AM53C974_write_8(CNTLREG1, (DEF_ETM<<7) | CNTLREG1_DISR | (DEF_PERE<<4) | instance->this_id);
        !           758: AM53C974_write_8(CNTLREG2, (DEF_ENF<<6));
        !           759: AM53C974_write_8(CNTLREG3, (DEF_ADIDCHK<<7) | (DEF_FASTSCSI<<4) | (DEF_FASTCLK<<3));
        !           760: AM53C974_write_8(CNTLREG4, (DEF_GLITCH<<6) | (DEF_PWD<<5) | (DEF_RAE<<3) | (DEF_RADE<<2) | CNTLREG4_RES);
        !           761: }
        !           762: 
        !           763: /***********************************************************************
        !           764: * Function : const char *AM53C974_info(struct Scsi_Host *instance)     *
        !           765: *                                                                      *
        !           766: * Purpose : return device driver information                           *
        !           767: *                                                                      *
        !           768: * Inputs : instance - which AM53C974                                   *
        !           769: *                                                                      *
        !           770: * Returns : info string                                                *
        !           771: ************************************************************************/
        !           772: const char *AM53C974_info(struct Scsi_Host *instance)
        !           773: {
        !           774: static char       info[100];
        !           775: 
        !           776: sprintf(info, "AM53/79C974 PCscsi driver rev. %d.%d; host I/O address: 0x%x; irq: %d\n", 
        !           777:         AM53C974_DRIVER_REVISION_MAJOR, AM53C974_DRIVER_REVISION_MINOR,
        !           778:         instance->io_port, instance->irq);
        !           779: return (info);
        !           780: }
        !           781: 
        !           782: /************************************************************************** 
        !           783: * Function : int AM53C974_command (Scsi_Cmnd *SCpnt)                      *
        !           784: *                                                                         *
        !           785: * Purpose : the unqueued SCSI command function, replaced by the           *
        !           786: *           AM53C974_queue_command function                               *
        !           787: *                                                                         *
        !           788: * Inputs : SCpnt - pointer to command structure                           *
        !           789: *                                                                         *
        !           790: * Returns :status, see hosts.h for details                                *
        !           791: ***************************************************************************/
        !           792: int AM53C974_command(Scsi_Cmnd *SCpnt)
        !           793: {
        !           794: DEB(printk("AM53C974_command called\n"));
        !           795: return 0;
        !           796: }
        !           797: 
        !           798: /**************************************************************************
        !           799: * Function : void initialize_SCp(Scsi_Cmnd *cmd)                          *
        !           800: *                                                                         *
        !           801: * Purpose : initialize the saved data pointers for cmd to point to the    *
        !           802: *          start of the buffer.                                          *                              
        !           803: *                                                                         *
        !           804: * Inputs : cmd - Scsi_Cmnd structure to have pointers reset.              *
        !           805: *                                                                         *
        !           806: * Returns : nothing                                                       *
        !           807: **************************************************************************/
        !           808: static __inline__ void initialize_SCp(Scsi_Cmnd *cmd)
        !           809: {
        !           810: if (cmd->use_sg) {
        !           811:    cmd->SCp.buffer = (struct scatterlist *)cmd->buffer;
        !           812:    cmd->SCp.buffers_residual = cmd->use_sg - 1;
        !           813:    cmd->SCp.ptr = (char *)cmd->SCp.buffer->address;
        !           814:    cmd->SCp.this_residual = cmd->SCp.buffer->length; }
        !           815:   else {
        !           816:    cmd->SCp.buffer = NULL;
        !           817:    cmd->SCp.buffers_residual = 0;
        !           818:    cmd->SCp.ptr = (char *)cmd->request_buffer;
        !           819:    cmd->SCp.this_residual = cmd->request_bufflen; }
        !           820: }
        !           821: 
        !           822: /**************************************************************************
        !           823: * Function : run_main(void)                                               *
        !           824: *                                                                         *
        !           825: * Purpose : insure that the coroutine is running and will process our     *
        !           826: *          request.  main_running is checked/set here (in an inline      *
        !           827: *           function rather than in AM53C974_main itself to reduce the    *
        !           828: *           chances of stack overflow.                                    *
        !           829: *                                                                         *
        !           830: *                                                                         *
        !           831: * Inputs : none                                                           *
        !           832: *                                                                         *
        !           833: * Returns : nothing                                                       *
        !           834: **************************************************************************/
        !           835: static __inline__ void run_main(void)
        !           836: {
        !           837: cli();
        !           838: if (!main_running) {
        !           839:    /* main_running is cleared in AM53C974_main once it can't do 
        !           840:       more work, and AM53C974_main exits with interrupts disabled. */
        !           841:    main_running = 1;
        !           842:    AM53C974_main();
        !           843:    sti(); }
        !           844:   else 
        !           845:    sti();
        !           846: }
        !           847: 
        !           848: /************************************************************************** 
        !           849: * Function : int AM53C974_queue_command(Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *))
        !           850: *
        !           851: * Purpose : writes SCSI command into AM53C974 FIFO 
        !           852: *
        !           853: * Inputs : cmd - SCSI command, done - function called on completion, with
        !           854: *      a pointer to the command descriptor.
        !           855: * 
        !           856: * Returns : status, see hosts.h for details
        !           857: *
        !           858: * Side effects : 
        !           859: *      cmd is added to the per instance issue_queue, with minor 
        !           860: *      twiddling done to the host specific fields of cmd.  If the 
        !           861: *      main coroutine is not running, it is restarted.
        !           862: **************************************************************************/
        !           863: int AM53C974_queue_command(Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *))
        !           864: {
        !           865: struct Scsi_Host         *instance = cmd->host;
        !           866: struct AM53C974_hostdata *hostdata = (struct AM53C974_hostdata *)instance->hostdata;
        !           867: Scsi_Cmnd                *tmp;
        !           868: 
        !           869: cli();
        !           870: DEB_QUEUE(printk(SEPARATOR_LINE));
        !           871: DEB_QUEUE(printk("scsi%d: AM53C974_queue_command called\n", instance->host_no));
        !           872: DEB_QUEUE(printk("cmd=%02x target=%02x lun=%02x bufflen=%d use_sg = %02x\n", 
        !           873:           cmd->cmnd[0], cmd->target, cmd->lun, cmd->request_bufflen, cmd->use_sg));
        !           874: 
        !           875: /* We use the host_scribble field as a pointer to the next command in a queue */
        !           876: cmd->host_scribble = NULL;
        !           877: cmd->scsi_done = done;
        !           878: cmd->result = 0;
        !           879: cmd->device->disconnect = 0;
        !           880: 
        !           881: /* Insert the cmd into the issue queue. Note that REQUEST SENSE 
        !           882:  * commands are added to the head of the queue since any command will
        !           883:  * clear the contingent allegiance condition that exists and the 
        !           884:  * sense data is only guaranteed to be valid while the condition exists. */
        !           885: if (!(hostdata->issue_queue) || (cmd->cmnd[0] == REQUEST_SENSE)) {
        !           886:    LIST(cmd, hostdata->issue_queue);
        !           887:    cmd->host_scribble = (unsigned char *)hostdata->issue_queue;
        !           888:    hostdata->issue_queue = cmd; }
        !           889:   else {
        !           890:    for (tmp = (Scsi_Cmnd *)hostdata->issue_queue; tmp->host_scribble; 
        !           891:        tmp = (Scsi_Cmnd *)tmp->host_scribble);
        !           892:    LIST(cmd, tmp);
        !           893:    tmp->host_scribble = (unsigned char *)cmd; }
        !           894: 
        !           895: DEB_QUEUE(printk("scsi%d : command added to %s of queue\n", instance->host_no,
        !           896:          (cmd->cmnd[0] == REQUEST_SENSE) ? "head" : "tail"));
        !           897: 
        !           898: /* Run the coroutine if it isn't already running. */
        !           899: run_main();
        !           900: return 0;
        !           901: }
        !           902: 
        !           903: /**************************************************************************
        !           904:  * Function : AM53C974_main (void) 
        !           905:  *
        !           906:  * Purpose : AM53C974_main is a coroutine that runs as long as more work can 
        !           907:  *     be done on the AM53C974 host adapters in a system.  Both 
        !           908:  *     AM53C974_queue_command() and AM53C974_intr() will try to start it 
        !           909:  *     in case it is not running.
        !           910:  * 
        !           911:  * NOTE : AM53C974_main exits with interrupts *disabled*, the caller should 
        !           912:  *  reenable them.  This prevents reentrancy and kernel stack overflow.
        !           913:  **************************************************************************/  
        !           914: static void AM53C974_main(void)
        !           915: {
        !           916: AM53C974_local_declare(); 
        !           917: Scsi_Cmnd                *tmp, *prev;
        !           918: struct Scsi_Host         *instance;
        !           919: struct AM53C974_hostdata *hostdata;
        !           920: int                      done;
        !           921: 
        !           922: /* We run (with interrupts disabled) until we're sure that none of 
        !           923:  * the host adapters have anything that can be done, at which point 
        !           924:  * we set main_running to 0 and exit. */
        !           925: 
        !           926: do {
        !           927:    cli(); /* Freeze request queues */
        !           928:    done = 1;
        !           929:    for (instance = first_instance; instance && instance->hostt == the_template;
        !           930:         instance = instance->next) {
        !           931:        hostdata = (struct AM53C974_hostdata *)instance->hostdata;
        !           932:        AM53C974_setio(instance);
        !           933:        /* start to select target if we are not connected and not in the 
        !           934:           selection process */
        !           935:        if (!hostdata->connected && !hostdata->sel_cmd) {
        !           936:           /* Search through the issue_queue for a command destined for a target 
        !           937:              that is not busy. */
        !           938:           for (tmp = (Scsi_Cmnd *)hostdata->issue_queue, prev = NULL; tmp; 
        !           939:                prev = tmp, tmp = (Scsi_Cmnd *)tmp->host_scribble) {
        !           940:              /*  When we find one, remove it from the issue queue. */
        !           941:              if (!(hostdata->busy[tmp->target] & (1 << tmp->lun))) {
        !           942:                 if (prev) {
        !           943:                    REMOVE(prev, (Scsi_Cmnd *)(prev->host_scribble), tmp,
        !           944:                            (Scsi_Cmnd *)(tmp->host_scribble));
        !           945:                    prev->host_scribble = tmp->host_scribble; } 
        !           946:                    else {
        !           947:                    REMOVE(-1, hostdata->issue_queue, tmp, tmp->host_scribble);
        !           948:                    hostdata->issue_queue = (Scsi_Cmnd *)tmp->host_scribble; }
        !           949:                 tmp->host_scribble = NULL;
        !           950: 
        !           951:                  /* go into selection mode, disable reselection and wait for
        !           952:                     SO interrupt which will continue with the selection process */
        !           953:                  hostdata->selecting = 1;
        !           954:                  hostdata->sel_cmd = tmp;
        !           955:                  AM53C974_write_8(CMDREG, CMDREG_DSR); 
        !           956:                  break;                 
        !           957:                 } /* if target/lun is not busy */
        !           958: 
        !           959:              } /* for */
        !           960:           } /* if (!hostdata->connected) */
        !           961:          else {                
        !           962:           DEB(printk("main: connected; cmd = 0x%lx, sel_cmd = 0x%lx\n",
        !           963:                  (long)hostdata->connected, (long)hostdata->sel_cmd));
        !           964:          }
        !           965:        } /* for instance */
        !           966:    } while (!done);
        !           967: main_running = 0;
        !           968: }
        !           969: 
        !           970: /************************************************************************
        !           971: * Function : AM53C974_intr(int irq, void *dev_id, struct pt_regs *regs) *
        !           972: *                                                                       *
        !           973: * Purpose : interrupt handler                                           *
        !           974: *                                                                       *
        !           975: * Inputs : irq - interrupt line, regs - ?                               *
        !           976: *                                                                       *
        !           977: * Returns : nothing                                                     *
        !           978: ************************************************************************/
        !           979: static void AM53C974_intr(int irq, void *dev_id, struct pt_regs *regs)
        !           980: {
        !           981: AM53C974_local_declare(); 
        !           982: struct Scsi_Host         *instance;
        !           983: struct AM53C974_hostdata *hostdata;
        !           984: unsigned char            cmdreg, dmastatus, statreg, isreg, instreg, cfifo;
        !           985: 
        !           986: /* find AM53C974 hostadapter responsible for this interrupt */
        !           987: for (instance = first_instance; instance; instance = instance->next)
        !           988:     if ((instance->irq == irq) && (instance->hostt == the_template)) goto FOUND;
        !           989: sti();
        !           990: return;
        !           991: 
        !           992: /* found; now decode and process */
        !           993: FOUND:
        !           994: hostdata = (struct AM53C974_hostdata *)instance->hostdata;
        !           995: AM53C974_setio(instance);
        !           996: dmastatus = AM53C974_read_8(DMASTATUS);
        !           997: 
        !           998: DEB_INTR(printk(SEPARATOR_LINE));
        !           999: DEB_INTR(printk("AM53C974 interrupt; dmastatus=0x%02x\n", dmastatus));
        !          1000: KEYWAIT();
        !          1001: 
        !          1002: /*** DMA related interrupts ***/
        !          1003: if (hostdata->connected && (dmastatus & (DMASTATUS_ERROR | DMASTATUS_PWDN | 
        !          1004:                                          DMASTATUS_ABORT))) {
        !          1005:    /* DMA error or POWERDOWN */
        !          1006:    printk("scsi%d: DMA error or powerdown; dmastatus: 0x%02x\n",
        !          1007:           instance->host_no, dmastatus);
        !          1008: #ifdef AM53C974_DEBUG
        !          1009:    deb_stop = 1;
        !          1010: #endif
        !          1011:    panic("scsi%d: cannot recover\n", instance->host_no); }
        !          1012: 
        !          1013: if (hostdata->connected && (dmastatus & DMASTATUS_DONE)) {     
        !          1014:    /* DMA transfer done */
        !          1015:    unsigned long residual;
        !          1016:    cli();
        !          1017:    if (!(AM53C974_read_8(DMACMD) & DMACMD_DIR)) {
        !          1018:       do {
        !          1019:          dmastatus = AM53C974_read_8(DMASTATUS);
        !          1020:          residual  = AM53C974_read_8(CTCLREG) | (AM53C974_read_8(CTCMREG) << 8) |
        !          1021:                     (AM53C974_read_8(CTCHREG) << 16);
        !          1022:          residual += AM53C974_read_8(CFIREG) & CFIREG_CF;
        !          1023:          } while (!(dmastatus & DMASTATUS_SCSIINT) && residual);
        !          1024:       residual = AM53C974_read_8(CTCLREG) | (AM53C974_read_8(CTCMREG) << 8) |
        !          1025:                  (AM53C974_read_8(CTCHREG) << 16);
        !          1026:       residual += AM53C974_read_8(CFIREG) & CFIREG_CF;
        !          1027:       }
        !          1028:      else
        !          1029:       residual = 0;
        !          1030:    hostdata->connected->SCp.ptr += hostdata->connected->SCp.this_residual - residual;
        !          1031:    hostdata->connected->SCp.this_residual = residual;
        !          1032: 
        !          1033:    AM53C974_write_8(DMACMD, DMACMD_IDLE);
        !          1034: 
        !          1035:    /* if service request missed before, process it now (ugly) */
        !          1036:    if (hostdata->dma_busy) {
        !          1037:       hostdata->dma_busy = 0;
        !          1038:       cmdreg = AM53C974_read_8(CMDREG);
        !          1039:       statreg = AM53C974_read_8(STATREG);
        !          1040:       isreg = AM53C974_read_8(ISREG);
        !          1041:       instreg = AM53C974_read_8(INSTREG);
        !          1042:       cfifo = AM53C974_cfifo();
        !          1043:       AM53C974_information_transfer(instance, statreg, isreg, instreg, cfifo,
        !          1044:                                     dmastatus); }
        !          1045:    sti();
        !          1046:    }
        !          1047:    
        !          1048: if (!(dmastatus & DMASTATUS_SCSIINT)) {
        !          1049:    sti();
        !          1050:    return; }
        !          1051: 
        !          1052: /*** SCSI related interrupts ***/
        !          1053: cmdreg = AM53C974_read_8(CMDREG);
        !          1054: statreg = AM53C974_read_8(STATREG);
        !          1055: isreg = AM53C974_read_8(ISREG);
        !          1056: instreg = AM53C974_read_8(INSTREG);
        !          1057: cfifo = AM53C974_cfifo();
        !          1058: 
        !          1059: DEB_INTR(printk("scsi%d: statreg: 0x%02x; isreg: 0x%02x; instreg: 0x%02x; cfifo: 0x%02x\n",
        !          1060:                 instance->host_no, statreg, isreg, instreg, cfifo));
        !          1061: 
        !          1062: if (statreg & STATREG_PE) {
        !          1063:    /* parity error */
        !          1064: #ifdef AM53C974_DEBUG
        !          1065:    deb_stop = 1;
        !          1066: #endif
        !          1067:    printk("scsi%d : PARITY error\n", instance->host_no);
        !          1068:    if (hostdata->connected) hostdata->sync_off[hostdata->connected->target] = 0; /* setup asynchronous transfer */
        !          1069:    hostdata->aborted = 1; }
        !          1070: 
        !          1071: if (statreg & STATREG_IOE) {
        !          1072:    /* illegal operation error */
        !          1073: #ifdef AM53C974_DEBUG
        !          1074:    deb_stop = 1;
        !          1075: #endif
        !          1076:    printk("scsi%d : ILLEGAL OPERATION error\n", instance->host_no);
        !          1077:    printk("cmdreg:  0x%02x; dmacmd:  0x%02x; statreg: 0x%02x; \n"
        !          1078:           "isreg:   0x%02x; instreg: 0x%02x; cfifo:   0x%02x\n",
        !          1079:            cmdreg, AM53C974_read_8(DMACMD), statreg, isreg, instreg, cfifo); }
        !          1080: if (hostdata->in_reset && (instreg & INSTREG_SRST)) {
        !          1081:    /* RESET INTERRUPT */
        !          1082: #ifdef AM53C974_DEBUG
        !          1083:    deb_stop = 1;
        !          1084: #endif
        !          1085:    DEB(printk("Bus reset interrupt received\n"));
        !          1086:    AM53C974_intr_bus_reset(instance);
        !          1087:    cli();
        !          1088:    if (hostdata->connected) {
        !          1089:       hostdata->connected->result = DID_RESET << 16;
        !          1090:       hostdata->connected->scsi_done((Scsi_Cmnd *)hostdata->connected);
        !          1091:       hostdata->connected = NULL; }
        !          1092:      else { 
        !          1093:       if (hostdata->sel_cmd) {
        !          1094:          hostdata->sel_cmd->result = DID_RESET << 16;
        !          1095:          hostdata->sel_cmd->scsi_done((Scsi_Cmnd *)hostdata->sel_cmd);
        !          1096:          hostdata->sel_cmd = NULL; }
        !          1097:       }
        !          1098:    sti();
        !          1099:    if (hostdata->in_reset == 1) goto EXIT;
        !          1100:      else return;
        !          1101:    }
        !          1102: 
        !          1103: if (instreg & INSTREG_ICMD) {
        !          1104:    /* INVALID COMMAND INTERRUPT */
        !          1105: #ifdef AM53C974_DEBUG
        !          1106:    deb_stop = 1;
        !          1107: #endif
        !          1108:    printk("scsi%d: Invalid command interrupt\n", instance->host_no);
        !          1109:    printk("cmdreg:  0x%02x; dmacmd:  0x%02x; statreg: 0x%02x; dmastatus: 0x%02x; \n"
        !          1110:           "isreg:   0x%02x; instreg: 0x%02x; cfifo:   0x%02x\n",
        !          1111:            cmdreg, AM53C974_read_8(DMACMD), statreg, dmastatus, isreg, instreg, cfifo);
        !          1112:    panic("scsi%d: cannot recover\n", instance->host_no); }
        !          1113: 
        !          1114: if (instreg & INSTREG_DIS) {
        !          1115:    /* DISCONNECT INTERRUPT */
        !          1116:    DEB_INTR(printk("Disconnect interrupt received; "));
        !          1117:    cli();
        !          1118:    AM53C974_intr_disconnect(instance);
        !          1119:    sti();
        !          1120:    goto EXIT; }
        !          1121: 
        !          1122: if (instreg & INSTREG_RESEL) {
        !          1123:    /* RESELECTION INTERRUPT */
        !          1124:    DEB_INTR(printk("Reselection interrupt received\n"));
        !          1125:    cli();
        !          1126:    AM53C974_intr_reselect(instance, statreg);
        !          1127:    sti();
        !          1128:    goto EXIT; }
        !          1129: 
        !          1130: if (instreg & INSTREG_SO) {
        !          1131:    DEB_INTR(printk("Successful operation interrupt received\n"));
        !          1132:    if (hostdata->selecting) {
        !          1133:       DEB_INTR(printk("DSR completed, starting select\n"));
        !          1134:       cli();
        !          1135:       AM53C974_select(instance, (Scsi_Cmnd *)hostdata->sel_cmd,
        !          1136:                           (hostdata->sel_cmd->cmnd[0] == REQUEST_SENSE) ? 
        !          1137:                                                   TAG_NONE : TAG_NEXT);
        !          1138:       hostdata->selecting = 0;
        !          1139:       AM53C974_set_sync(instance, hostdata->sel_cmd->target);
        !          1140:       sti();
        !          1141:       return; }
        !          1142: 
        !          1143:    if (hostdata->sel_cmd != NULL) {
        !          1144:       if ( ((isreg & ISREG_IS) != ISREG_OK_NO_STOP) &&
        !          1145:            ((isreg & ISREG_IS) != ISREG_OK_STOP) ) {
        !          1146:          /* UNSUCCESSFUL SELECTION */
        !          1147:          DEB_INTR(printk("unsuccessful selection\n"));
        !          1148:          cli();
        !          1149:          hostdata->dma_busy = 0;
        !          1150:         LIST(hostdata->sel_cmd, hostdata->issue_queue);
        !          1151:         hostdata->sel_cmd->host_scribble = (unsigned char *)hostdata->issue_queue;
        !          1152:          hostdata->issue_queue = hostdata->sel_cmd;
        !          1153:          hostdata->sel_cmd = NULL;
        !          1154:          hostdata->selecting = 0;
        !          1155:          sti();
        !          1156:          goto EXIT; }
        !          1157:         else {
        !          1158:          /* SUCCESSFUL SELECTION */
        !          1159:          DEB(printk("successful selection; cmd=0x%02lx\n", (long)hostdata->sel_cmd));
        !          1160:          cli();
        !          1161:          hostdata->dma_busy = 0;
        !          1162:          hostdata->disconnecting = 0;
        !          1163:          hostdata->connected = hostdata->sel_cmd;
        !          1164:          hostdata->sel_cmd = NULL;
        !          1165:          hostdata->selecting = 0;
        !          1166: #ifdef SCSI2
        !          1167:          if (!hostdata->connected->device->tagged_queue)
        !          1168: #endif    
        !          1169:             hostdata->busy[hostdata->connected->target] |= (1 << hostdata->connected->lun);
        !          1170:          /* very strange -- use_sg is sometimes nonzero for request sense commands !! */
        !          1171:          if ((hostdata->connected->cmnd[0] == REQUEST_SENSE) && hostdata->connected->use_sg) {
        !          1172:             DEB(printk("scsi%d: REQUEST_SENSE command with nonzero use_sg\n", instance->host_no));
        !          1173:             KEYWAIT();
        !          1174:             hostdata->connected->use_sg = 0; }
        !          1175:          initialize_SCp((Scsi_Cmnd *)hostdata->connected);
        !          1176:          hostdata->connected->SCp.phase = PHASE_CMDOUT;
        !          1177:          AM53C974_information_transfer(instance, statreg, isreg, instreg, cfifo, dmastatus);
        !          1178:          sti();
        !          1179:          return; }
        !          1180:       }
        !          1181:      else {
        !          1182:       cli();
        !          1183:       AM53C974_information_transfer(instance, statreg, isreg, instreg, cfifo, dmastatus);
        !          1184:       sti();
        !          1185:       return; }
        !          1186:    }
        !          1187:     
        !          1188: if (instreg & INSTREG_SR) {
        !          1189:    DEB_INTR(printk("Service request interrupt received, "));
        !          1190:    if (hostdata->connected) {
        !          1191:       DEB_INTR(printk("calling information_transfer\n"));
        !          1192:       cli();
        !          1193:       AM53C974_information_transfer(instance, statreg, isreg, instreg, cfifo, dmastatus);
        !          1194:       sti(); }
        !          1195:      else {
        !          1196:       printk("scsi%d: weird: service request when no command connected\n", instance->host_no);
        !          1197:       AM53C974_write_8(CMDREG, CMDREG_CFIFO); }   /* clear FIFO */
        !          1198:    return;
        !          1199:    }
        !          1200: 
        !          1201: EXIT:
        !          1202:   DEB_INTR(printk("intr: starting main\n"));
        !          1203:   run_main();
        !          1204:   DEB_INTR(printk("end of intr\n"));
        !          1205: }
        !          1206: 
        !          1207: /************************************************************************** 
        !          1208: * Function : AM53C974_intr_disconnect(struct Scsi_Host *instance)
        !          1209: *
        !          1210: * Purpose : manage target disconnection
        !          1211: *
        !          1212: * Inputs : instance -- which AM53C974
        !          1213: * 
        !          1214: * Returns : nothing
        !          1215: **************************************************************************/
        !          1216: static void AM53C974_intr_disconnect(struct Scsi_Host *instance) 
        !          1217: {
        !          1218: AM53C974_local_declare(); 
        !          1219: struct AM53C974_hostdata *hostdata = (struct AM53C974_hostdata *)instance->hostdata;
        !          1220: Scsi_Cmnd                *cmd;
        !          1221: AM53C974_setio(instance);
        !          1222: 
        !          1223: if (hostdata->sel_cmd != NULL) {
        !          1224:    /* normal selection timeout, typical for nonexisting targets */
        !          1225:    cmd = (Scsi_Cmnd *)hostdata->sel_cmd;
        !          1226:    DEB_INTR(printk("bad target\n"));
        !          1227:    cmd->result = DID_BAD_TARGET << 16;
        !          1228:    goto EXIT_FINISHED; }
        !          1229: 
        !          1230: if (!hostdata->connected) {
        !          1231:    /* can happen if controller was reset, a device tried to reconnect,
        !          1232:       failed and disconnects now */
        !          1233:    AM53C974_write_8(CMDREG, CMDREG_CFIFO);
        !          1234:    return; }
        !          1235: 
        !          1236: if (hostdata->disconnecting) {
        !          1237:    /* target sent disconnect message, so we are prepared */
        !          1238:    cmd = (Scsi_Cmnd *)hostdata->connected;
        !          1239:    AM53C974_set_async(instance, cmd->target);
        !          1240:    DEB_INTR(printk("scsi%d : disc. from cmnd %d for ta %d, lun %d\n",
        !          1241:                   instance->host_no, cmd->cmnd[0], cmd->target, cmd->lun));
        !          1242:    if (cmd->device->disconnect) {
        !          1243:       /* target wants to reselect later */
        !          1244:       DEB_INTR(printk("ok, re-enabling selection\n"));
        !          1245:       LIST(cmd,hostdata->disconnected_queue);
        !          1246:       cmd->host_scribble = (unsigned char *)hostdata->disconnected_queue;
        !          1247:       hostdata->disconnected_queue = cmd;
        !          1248:       DEB_QUEUE(printk("scsi%d : command for target %d lun %d this %d was moved from connected to"
        !          1249:                       "  the disconnected_queue\n", instance->host_no, cmd->target,
        !          1250:                         cmd->lun, hostdata->disconnected_queue->SCp.this_residual));
        !          1251:       DEB_QUEUE(AM53C974_print_queues(instance));
        !          1252:       goto EXIT_UNFINISHED; }
        !          1253:      else {
        !          1254:       /* target does not want to reselect later, we are really finished */
        !          1255: #ifdef AM53C974_DEBUG
        !          1256:       if (cmd->cmnd[0] == REQUEST_SENSE) {
        !          1257:         int i;
        !          1258:         printk("Request sense data dump:\n");
        !          1259:         for (i = 0; i < cmd->request_bufflen; i++) {
        !          1260:              printk("%02x ", *((char *)(cmd->request_buffer) + i));
        !          1261:              if (i && !(i % 16)) printk("\n"); }
        !          1262:         printk("\n"); }
        !          1263: #endif
        !          1264:       goto EXIT_FINISHED; } /* !cmd->device->disconnect */
        !          1265:    } /* if (hostdata->disconnecting) */
        !          1266: 
        !          1267: /* no disconnect message received; unexpected disconnection */
        !          1268: cmd = (Scsi_Cmnd *)hostdata->connected;
        !          1269: if (cmd) {
        !          1270: #ifdef AM53C974_DEBUG
        !          1271:    deb_stop = 1;
        !          1272: #endif
        !          1273:    AM53C974_set_async(instance, cmd->target);
        !          1274:    printk("scsi%d: Unexpected disconnect; phase: %d; target: %d; this_residual: %d; buffers_residual: %d; message: %d\n",
        !          1275:            instance->host_no, cmd->SCp.phase, cmd->target, cmd->SCp.this_residual, cmd->SCp.buffers_residual,
        !          1276:            cmd->SCp.Message);
        !          1277:    printk("cmdreg: 0x%02x; statreg: 0x%02x; isreg: 0x%02x; cfifo: 0x%02x\n",
        !          1278:           AM53C974_read_8(CMDREG), AM53C974_read_8(STATREG), AM53C974_read_8(ISREG),
        !          1279:            AM53C974_read_8(CFIREG) & CFIREG_CF);
        !          1280: 
        !          1281:     if ((hostdata->last_message[0] == EXTENDED_MESSAGE) && 
        !          1282:         (hostdata->last_message[2] == EXTENDED_SDTR)) {
        !          1283:         /* sync. negotiation was aborted, setup asynchronous transfer with target */
        !          1284:         hostdata->sync_off[cmd->target] = 0; }
        !          1285:    if (hostdata->aborted || hostdata->msgout[0] == ABORT)
        !          1286:       cmd->result = DID_ABORT << 16;
        !          1287:      else
        !          1288:       cmd->result = DID_ERROR << 16;
        !          1289:    goto EXIT_FINISHED; }
        !          1290: 
        !          1291: EXIT_FINISHED:
        !          1292: hostdata->aborted = 0;
        !          1293: hostdata->msgout[0] = NOP;
        !          1294: hostdata->sel_cmd = NULL;
        !          1295: hostdata->connected = NULL;
        !          1296: hostdata->selecting = 0;
        !          1297: hostdata->disconnecting = 0;
        !          1298: hostdata->dma_busy = 0;
        !          1299: hostdata->busy[cmd->target] &= ~(1 << cmd->lun);
        !          1300: AM53C974_write_8(CMDREG, CMDREG_CFIFO);
        !          1301: DEB(printk("disconnect; issue_queue: 0x%lx, disconnected_queue: 0x%lx\n", 
        !          1302:        (long)hostdata->issue_queue, (long)hostdata->disconnected_queue));
        !          1303: cmd->scsi_done(cmd);
        !          1304: 
        !          1305: if (!hostdata->selecting) {
        !          1306:    AM53C974_set_async(instance, cmd->target); 
        !          1307:    AM53C974_write_8(CMDREG, CMDREG_ESR); } /* allow reselect */
        !          1308: return;
        !          1309: 
        !          1310: EXIT_UNFINISHED:
        !          1311: hostdata->msgout[0] = NOP;
        !          1312: hostdata->sel_cmd = NULL;
        !          1313: hostdata->connected = NULL;
        !          1314: hostdata->aborted = 0;
        !          1315: hostdata->selecting = 0;
        !          1316: hostdata->disconnecting = 0;
        !          1317: hostdata->dma_busy = 0;
        !          1318: DEB(printk("disconnect; issue_queue: 0x%lx, disconnected_queue: 0x%lx\n", 
        !          1319:        (long)hostdata->issue_queue, (long)hostdata->disconnected_queue));
        !          1320: if (!hostdata->selecting) {
        !          1321:    AM53C974_set_async(instance, cmd->target); 
        !          1322:    AM53C974_write_8(CMDREG, CMDREG_ESR); } /* allow reselect */
        !          1323: return;
        !          1324: }
        !          1325: 
        !          1326: /************************************************************************** 
        !          1327: * Function : int AM53C974_sync_neg(struct Scsi_Host *instance, int target, unsigned char *msg)
        !          1328: *
        !          1329: * Purpose : setup message string for sync. negotiation
        !          1330: *
        !          1331: * Inputs : instance -- which AM53C974
        !          1332: *          target -- which SCSI target to deal with
        !          1333: *          msg -- input message string
        !          1334: * 
        !          1335: * Returns : 0 if parameters accepted or 1 if not accepted
        !          1336: *
        !          1337: * Side effects: hostdata is changed
        !          1338: *
        !          1339: * Note: we assume here that fastclk is enabled
        !          1340: **************************************************************************/
        !          1341: static int AM53C974_sync_neg(struct Scsi_Host *instance, int target, unsigned char *msg) 
        !          1342: {
        !          1343: AM53C974_local_declare(); 
        !          1344: struct AM53C974_hostdata *hostdata = (struct AM53C974_hostdata *)instance->hostdata;
        !          1345: int                      period, offset, i, rate, rate_rem;
        !          1346: AM53C974_setio(instance);
        !          1347: 
        !          1348: period = (DEF_CLK * msg[3] * 8 + 1000) / 2000;
        !          1349: if (period < MIN_PERIOD) {
        !          1350:     period = MIN_PERIOD;
        !          1351:     hostdata->msgout[3] = period / 4; }
        !          1352:    else
        !          1353:     if (period > MAX_PERIOD) {
        !          1354:        period = MAX_PERIOD;
        !          1355:        hostdata->msgout[3] = period / 4; }
        !          1356:       else
        !          1357:        hostdata->msgout[3] = msg[3];
        !          1358: offset = msg[4]; 
        !          1359: if (offset > MAX_OFFSET) offset = MAX_OFFSET;
        !          1360: hostdata->msgout[4] = offset;
        !          1361: hostdata->sync_per[target] = period;
        !          1362: hostdata->sync_off[target] = offset;
        !          1363: for (i = 0; i < 3; i++) hostdata->msgout[i] = msg[i];
        !          1364: if ((hostdata->msgout[3] != msg[3]) || (msg[4] != offset)) return(1);
        !          1365: 
        !          1366: rate = DEF_CLK / period;
        !          1367: rate_rem = 10 * (DEF_CLK - period * rate) / period;
        !          1368: 
        !          1369: if (offset)
        !          1370:    printk("\ntarget %d: rate=%d.%d Mhz, synchronous, sync offset=%d bytes\n",
        !          1371:           target, rate, rate_rem, offset);
        !          1372:   else
        !          1373:    printk("\ntarget %d: rate=%d.%d Mhz, asynchronous\n", target, rate, rate_rem);
        !          1374: 
        !          1375: return(0);
        !          1376: }
        !          1377: 
        !          1378: /************************************************************************** 
        !          1379: * Function : AM53C974_set_async(struct Scsi_Host *instance, int target)
        !          1380: *
        !          1381: * Purpose : put controller into async. mode
        !          1382: *
        !          1383: * Inputs : instance -- which AM53C974
        !          1384: *          target -- which SCSI target to deal with
        !          1385: * 
        !          1386: * Returns : nothing
        !          1387: **************************************************************************/
        !          1388: static __inline__ void AM53C974_set_async(struct Scsi_Host *instance, int target)
        !          1389: {
        !          1390: AM53C974_local_declare(); 
        !          1391: struct AM53C974_hostdata *hostdata = (struct AM53C974_hostdata *)instance->hostdata;
        !          1392: AM53C974_setio(instance);
        !          1393: 
        !          1394: AM53C974_write_8(STPREG, hostdata->sync_per[target]);
        !          1395: AM53C974_write_8(SOFREG, (DEF_SOF_RAD<<6) | (DEF_SOF_RAA<<4));
        !          1396: }
        !          1397: 
        !          1398: /************************************************************************** 
        !          1399: * Function : AM53C974_set_sync(struct Scsi_Host *instance, int target)
        !          1400: *
        !          1401: * Purpose : put controller into sync. mode
        !          1402: *
        !          1403: * Inputs : instance -- which AM53C974
        !          1404: *          target -- which SCSI target to deal with
        !          1405: * 
        !          1406: * Returns : nothing
        !          1407: **************************************************************************/
        !          1408: static __inline__ void AM53C974_set_sync(struct Scsi_Host *instance, int target)
        !          1409: {
        !          1410: AM53C974_local_declare(); 
        !          1411: struct AM53C974_hostdata *hostdata = (struct AM53C974_hostdata *)instance->hostdata;
        !          1412: AM53C974_setio(instance);
        !          1413: 
        !          1414: AM53C974_write_8(STPREG, hostdata->sync_per[target]);
        !          1415: AM53C974_write_8(SOFREG, (SOFREG_SO & hostdata->sync_off[target]) | 
        !          1416:                 (DEF_SOF_RAD<<6) | (DEF_SOF_RAA<<4));
        !          1417: }
        !          1418: 
        !          1419: /***********************************************************************
        !          1420: * Function : AM53C974_information_transfer(struct Scsi_Host *instance, *
        !          1421: *                          unsigned char statreg, unsigned char isreg, *
        !          1422: *                         unsigned char instreg, unsigned char cfifo,  *
        !          1423: *                         unsigned char dmastatus)                     *
        !          1424: *                                                                      *
        !          1425: * Purpose : handle phase changes                                       *
        !          1426: *                                                                      *
        !          1427: * Inputs : instance - which AM53C974                                   *
        !          1428: *          statreg - status register                                     *
        !          1429: *          isreg - internal state register                             *
        !          1430: *          instreg - interrupt status register                         *
        !          1431: *          cfifo - number of bytes in FIFO                             *
        !          1432: *          dmastatus - dma status register                             *
        !          1433: *                                                                      *
        !          1434: * Returns : nothing                                                    *
        !          1435: ************************************************************************/
        !          1436: static void AM53C974_information_transfer(struct Scsi_Host *instance, 
        !          1437:                                           unsigned char statreg, unsigned char isreg,
        !          1438:                                           unsigned char instreg, unsigned char cfifo,
        !          1439:                                           unsigned char dmastatus)
        !          1440: {
        !          1441: AM53C974_local_declare(); 
        !          1442: struct AM53C974_hostdata *hostdata = (struct AM53C974_hostdata *)instance->hostdata;
        !          1443: Scsi_Cmnd                *cmd = (Scsi_Cmnd *)hostdata->connected;
        !          1444: int                      ret, i, len, residual=-1;
        !          1445: AM53C974_setio(instance);
        !          1446: 
        !          1447: DEB_INFO(printk(SEPARATOR_LINE));
        !          1448: switch (statreg & STATREG_PHASE) {     /* scsi phase */
        !          1449:   case PHASE_DATAOUT:
        !          1450:     DEB_INFO(printk("Dataout phase; cmd=0x%lx, sel_cmd=0x%lx, this_residual=%d, buffers_residual=%d\n",
        !          1451:                     (long)hostdata->connected, (long)hostdata->sel_cmd, cmd->SCp.this_residual, cmd->SCp.buffers_residual));
        !          1452:     cmd->SCp.phase = PHASE_DATAOUT;
        !          1453:     goto PHASE_DATA_IO;
        !          1454: 
        !          1455:   case PHASE_DATAIN:
        !          1456:     DEB_INFO(printk("Datain phase; cmd=0x%lx, sel_cmd=0x%lx, this_residual=%d, buffers_residual=%d\n",
        !          1457:                      (long)hostdata->connected, (long)hostdata->sel_cmd, cmd->SCp.this_residual, cmd->SCp.buffers_residual));
        !          1458:     cmd->SCp.phase = PHASE_DATAIN;
        !          1459:     PHASE_DATA_IO:
        !          1460:     if (hostdata->aborted) {
        !          1461:        AM53C974_write_8(DMACMD, DMACMD_IDLE);
        !          1462:        AM53C974_write_8(CMDREG, CMDREG_CFIFO);
        !          1463:        AM53C974_write_8(CMDREG, CMDREG_SATN);
        !          1464:        return; }
        !          1465:     if ((!cmd->SCp.this_residual) && cmd->SCp.buffers_residual) {
        !          1466:        cmd->SCp.buffer++;
        !          1467:        cmd->SCp.buffers_residual--;
        !          1468:        cmd->SCp.ptr = (unsigned char *)cmd->SCp.buffer->address;
        !          1469:        cmd->SCp.this_residual = cmd->SCp.buffer->length; }
        !          1470:     if (cmd->SCp.this_residual) {
        !          1471:        if (!(AM53C974_read_8(DMACMD) & DMACMD_START)) {
        !          1472:           hostdata->dma_busy = 0;
        !          1473:           AM53C974_transfer_dma(instance, statreg & STATREG_IO,
        !          1474:                                 (unsigned long)cmd->SCp.this_residual,
        !          1475:                                 cmd->SCp.ptr); }
        !          1476:          else
        !          1477:           hostdata->dma_busy = 1;
        !          1478:        }
        !          1479:     return;
        !          1480: 
        !          1481:   case PHASE_MSGIN:
        !          1482:     DEB_INFO(printk("Message-In phase; cmd=0x%lx, sel_cmd=0x%lx\n",
        !          1483:                     (long)hostdata->connected, (long)hostdata->sel_cmd));
        !          1484:     AM53C974_set_async(instance, cmd->target);
        !          1485:     if (cmd->SCp.phase == PHASE_DATAIN)
        !          1486:        AM53C974_dma_blast(instance, dmastatus, statreg);
        !          1487:     if ((cmd->SCp.phase == PHASE_DATAOUT) && (AM53C974_read_8(DMACMD) & DMACMD_START)) {
        !          1488:        AM53C974_write_8(DMACMD, DMACMD_IDLE);
        !          1489:        residual = cfifo + (AM53C974_read_8(CTCLREG) | (AM53C974_read_8(CTCMREG) << 8) |
        !          1490:                           (AM53C974_read_8(CTCHREG) << 16));
        !          1491:        cmd->SCp.ptr += cmd->SCp.this_residual - residual;
        !          1492:        cmd->SCp.this_residual = residual;
        !          1493:        if (cfifo) { AM53C974_write_8(CMDREG, CMDREG_CFIFO); cfifo = 0; }
        !          1494:        }
        !          1495:     if (cmd->SCp.phase == PHASE_STATIN) {
        !          1496:        while ((AM53C974_read_8(CFIREG) & CFIREG_CF) < 2) ;
        !          1497:        cmd->SCp.Status = AM53C974_read_8(FFREG);
        !          1498:        cmd->SCp.Message = AM53C974_read_8(FFREG); 
        !          1499:        DEB_INFO(printk("Message-In phase; status=0x%02x, message=0x%02x\n",
        !          1500:                        cmd->SCp.Status, cmd->SCp.Message));
        !          1501:        ret = AM53C974_message(instance, cmd, cmd->SCp.Message); }
        !          1502:       else {
        !          1503:        if (!cfifo) {
        !          1504:           AM53C974_write_8(CMDREG, CMDREG_IT); 
        !          1505:           AM53C974_poll_int();
        !          1506:           cmd->SCp.Message = AM53C974_read_8(FFREG);
        !          1507:           }
        !          1508:        ret = AM53C974_message(instance, cmd, cmd->SCp.Message);
        !          1509:        }
        !          1510:     cmd->SCp.phase = PHASE_MSGIN;
        !          1511:     AM53C974_set_sync(instance, cmd->target);
        !          1512:     break;
        !          1513:   case PHASE_MSGOUT:
        !          1514:     DEB_INFO(printk("Message-Out phase; cfifo=%d; msgout[0]=0x%02x\n",
        !          1515:                     AM53C974_read_8(CFIREG) & CFIREG_CF, hostdata->msgout[0]));
        !          1516:     AM53C974_write_8(DMACMD, DMACMD_IDLE);
        !          1517:     AM53C974_set_async(instance, cmd->target);
        !          1518:     for (i = 0; i < sizeof(hostdata->last_message); i++) 
        !          1519:         hostdata->last_message[i] = hostdata->msgout[i];
        !          1520:     if ((hostdata->msgout[0] == 0) || INSIDE(hostdata->msgout[0], 0x02, 0x1F) || 
        !          1521:         INSIDE(hostdata->msgout[0], 0x80, 0xFF)) 
        !          1522:        len = 1;
        !          1523:       else {
        !          1524:        if (hostdata->msgout[0] == EXTENDED_MESSAGE) {
        !          1525: #ifdef AM53C974_DEBUG_INFO
        !          1526:           printk("Extended message dump:\n");
        !          1527:           for (i = 0; i < hostdata->msgout[1] + 2; i++) {
        !          1528:               printk("%02x ", hostdata->msgout[i]);
        !          1529:               if (i && !(i % 16)) printk("\n"); }
        !          1530:           printk("\n");
        !          1531: #endif
        !          1532:           len = hostdata->msgout[1] + 2; }
        !          1533:          else
        !          1534:           len = 2;
        !          1535:        }
        !          1536:     for (i = 0; i < len; i++) AM53C974_write_8(FFREG, hostdata->msgout[i]);
        !          1537:     AM53C974_write_8(CMDREG, CMDREG_IT);
        !          1538:     cmd->SCp.phase = PHASE_MSGOUT;
        !          1539:     hostdata->msgout[0] = NOP;
        !          1540:     AM53C974_set_sync(instance, cmd->target);
        !          1541:     break;
        !          1542: 
        !          1543:   case PHASE_CMDOUT:
        !          1544:     DEB_INFO(printk("Command-Out phase\n"));
        !          1545:     AM53C974_set_async(instance, cmd->target);
        !          1546:     for (i = 0; i < cmd->cmd_len; i++) AM53C974_write_8(FFREG, cmd->cmnd[i]);
        !          1547:     AM53C974_write_8(CMDREG, CMDREG_IT);
        !          1548:     cmd->SCp.phase = PHASE_CMDOUT;
        !          1549:     AM53C974_set_sync(instance, cmd->target);
        !          1550:     break;
        !          1551: 
        !          1552:   case PHASE_STATIN:
        !          1553:     DEB_INFO(printk("Status phase\n"));
        !          1554:     if (cmd->SCp.phase == PHASE_DATAIN)
        !          1555:        AM53C974_dma_blast(instance, dmastatus, statreg);
        !          1556:     AM53C974_set_async(instance, cmd->target);
        !          1557:     if (cmd->SCp.phase == PHASE_DATAOUT) {
        !          1558:        unsigned long residual;
        !          1559: 
        !          1560:        if (AM53C974_read_8(DMACMD) & DMACMD_START) {
        !          1561:           AM53C974_write_8(DMACMD, DMACMD_IDLE);
        !          1562:           residual = cfifo + (AM53C974_read_8(CTCLREG) | (AM53C974_read_8(CTCMREG) << 8) |
        !          1563:                               (AM53C974_read_8(CTCHREG) << 16));
        !          1564:           cmd->SCp.ptr += cmd->SCp.this_residual - residual;
        !          1565:           cmd->SCp.this_residual = residual; }
        !          1566:        if (cfifo) { AM53C974_write_8(CMDREG, CMDREG_CFIFO); cfifo = 0; }
        !          1567:        }
        !          1568:     cmd->SCp.phase = PHASE_STATIN;
        !          1569:     AM53C974_write_8(CMDREG, CMDREG_ICCS);  /* command complete */
        !          1570:     break;
        !          1571: 
        !          1572:   case PHASE_RES_0:
        !          1573:   case PHASE_RES_1:
        !          1574: #ifdef AM53C974_DEBUG
        !          1575:    deb_stop = 1;
        !          1576: #endif
        !          1577:     DEB_INFO(printk("Reserved phase\n"));
        !          1578:     break;
        !          1579:   }
        !          1580: KEYWAIT();
        !          1581: }
        !          1582: 
        !          1583: /******************************************************************************
        !          1584: * Function : int AM53C974_message(struct Scsi_Host *instance, Scsi_Cmnd *cmd,
        !          1585: *                                 unsigned char msg)                
        !          1586: *
        !          1587: * Purpose : handle SCSI messages
        !          1588: *
        !          1589: * Inputs : instance -- which AM53C974
        !          1590: *          cmd -- SCSI command the message belongs to
        !          1591: *          msg -- message id byte
        !          1592: * 
        !          1593: * Returns : 1 on success, 0 on failure.
        !          1594: **************************************************************************/
        !          1595: static int AM53C974_message(struct Scsi_Host *instance, Scsi_Cmnd *cmd,
        !          1596:                             unsigned char msg)
        !          1597: {
        !          1598: AM53C974_local_declare(); 
        !          1599: static unsigned char     extended_msg[10];
        !          1600: unsigned char            statreg;
        !          1601: int                      len, ret = 0;
        !          1602: unsigned char            *p;
        !          1603: #ifdef AM53C974_DEBUG_MSG
        !          1604: int                      j;
        !          1605: #endif
        !          1606: struct AM53C974_hostdata *hostdata = (struct AM53C974_hostdata *)instance->hostdata;
        !          1607: AM53C974_setio(instance);
        !          1608: 
        !          1609: DEB_MSG(printk(SEPARATOR_LINE));
        !          1610: 
        !          1611: /* Linking lets us reduce the time required to get the 
        !          1612:  * next command out to the device, hopefully this will
        !          1613:  * mean we don't waste another revolution due to the delays
        !          1614:  * required by ARBITRATION and another SELECTION.
        !          1615:  * In the current implementation proposal, low level drivers
        !          1616:  * merely have to start the next command, pointed to by 
        !          1617:  * next_link, done() is called as with unlinked commands. */
        !          1618: switch (msg) {
        !          1619: #ifdef LINKED
        !          1620:   case LINKED_CMD_COMPLETE:
        !          1621:   case LINKED_FLG_CMD_COMPLETE:
        !          1622:     /* Accept message by releasing ACK */
        !          1623:     DEB_LINKED(printk("scsi%d : target %d lun %d linked command complete.\n",
        !          1624:                        instance->host_no, cmd->target, cmd->lun));
        !          1625:     /* Sanity check : A linked command should only terminate with
        !          1626:      * one of these messages if there are more linked commands available. */
        !          1627:     if (!cmd->next_link) {
        !          1628:        printk("scsi%d : target %d lun %d linked command complete, no next_link\n"
        !          1629:               instance->host_no, cmd->target, cmd->lun);
        !          1630:        hostdata->aborted = 1;
        !          1631:        AM53C974_write_8(CMDREG, CMDREG_SATN);
        !          1632:        AM53C974_write_8(CMDREG, CMDREG_MA);
        !          1633:        break; }
        !          1634:     if (hostdata->aborted) {
        !          1635:        DEB_ABORT(printk("ATN set for cmnd %d upon reception of LINKED_CMD_COMPLETE or"
        !          1636:                         "LINKED_FLG_CMD_COMPLETE message\n", cmd->cmnd[0]));
        !          1637:        AM53C974_write_8(CMDREG, CMDREG_SATN); }
        !          1638:     AM53C974_write_8(CMDREG, CMDREG_MA);
        !          1639: 
        !          1640:     initialize_SCp(cmd->next_link);
        !          1641:     /* The next command is still part of this process */
        !          1642:     cmd->next_link->tag = cmd->tag;
        !          1643:     cmd->result = cmd->SCp.Status | (cmd->SCp.Message << 8); 
        !          1644:     DEB_LINKED(printk("scsi%d : target %d lun %d linked request done, calling scsi_done().\n",
        !          1645:                      instance->host_no, cmd->target, cmd->lun));
        !          1646:     cmd->scsi_done(cmd);
        !          1647:     cmd = hostdata->connected;
        !          1648:     break;
        !          1649: 
        !          1650: #endif /* def LINKED */
        !          1651: 
        !          1652:   case ABORT:
        !          1653:   case COMMAND_COMPLETE: 
        !          1654:     DEB_MSG(printk("scsi%d: command complete message received; cmd %d for target %d, lun %d\n",
        !          1655:                   instance->host_no, cmd->cmnd[0], cmd->target, cmd->lun));
        !          1656:     hostdata->disconnecting = 1;
        !          1657:     cmd->device->disconnect = 0;
        !          1658: 
        !          1659:     /* I'm not sure what the correct thing to do here is : 
        !          1660:      * 
        !          1661:      * If the command that just executed is NOT a request 
        !          1662:      * sense, the obvious thing to do is to set the result
        !          1663:      * code to the values of the stored parameters.
        !          1664:      * If it was a REQUEST SENSE command, we need some way 
        !          1665:      * to differentiate between the failure code of the original
        !          1666:      * and the failure code of the REQUEST sense - the obvious
        !          1667:      * case is success, where we fall through and leave the result
        !          1668:      * code unchanged.
        !          1669:      * 
        !          1670:      * The non-obvious place is where the REQUEST SENSE failed  */
        !          1671:     if (cmd->cmnd[0] != REQUEST_SENSE) 
        !          1672:        cmd->result = cmd->SCp.Status | (cmd->SCp.Message << 8); 
        !          1673:       else if (cmd->SCp.Status != GOOD)
        !          1674:        cmd->result = (cmd->result & 0x00ffff) | (DID_ERROR << 16);                 
        !          1675:     if (hostdata->aborted) {
        !          1676:        AM53C974_write_8(CMDREG, CMDREG_SATN);
        !          1677:        AM53C974_write_8(CMDREG, CMDREG_MA);
        !          1678:        DEB_ABORT(printk("ATN set for cmnd %d upon reception of ABORT or"
        !          1679:                         "COMMAND_COMPLETE message\n", cmd->cmnd[0]));
        !          1680:        break; }
        !          1681:     if ((cmd->cmnd[0] != REQUEST_SENSE) && (cmd->SCp.Status == CHECK_CONDITION)) {
        !          1682:        DEB_MSG(printk("scsi%d : performing request sense\n", instance->host_no));
        !          1683:        cmd->cmnd[0] = REQUEST_SENSE;
        !          1684:        cmd->cmnd[1] &= 0xe0;
        !          1685:        cmd->cmnd[2] = 0;
        !          1686:        cmd->cmnd[3] = 0;
        !          1687:        cmd->cmnd[4] = sizeof(cmd->sense_buffer);
        !          1688:        cmd->cmnd[5] = 0;
        !          1689:        cmd->SCp.buffer = NULL;
        !          1690:        cmd->SCp.buffers_residual = 0;
        !          1691:        cmd->SCp.ptr = (char *)cmd->sense_buffer;
        !          1692:        cmd->SCp.this_residual = sizeof(cmd->sense_buffer);
        !          1693:        LIST(cmd,hostdata->issue_queue);
        !          1694:        cmd->host_scribble = (unsigned char *)hostdata->issue_queue;
        !          1695:        hostdata->issue_queue = (Scsi_Cmnd *)cmd;
        !          1696:        DEB_MSG(printk("scsi%d : REQUEST SENSE added to head of issue queue\n",instance->host_no));
        !          1697:        }
        !          1698: 
        !          1699:     /* Accept message by clearing ACK */
        !          1700:     AM53C974_write_8(CMDREG, CMDREG_MA);
        !          1701:     break;
        !          1702:                
        !          1703:   case MESSAGE_REJECT:
        !          1704:     DEB_MSG(printk("scsi%d: reject message received; cmd %d for target %d, lun %d\n",
        !          1705:                   instance->host_no, cmd->cmnd[0], cmd->target, cmd->lun));
        !          1706:     switch (hostdata->last_message[0]) {
        !          1707:       case EXTENDED_MESSAGE:
        !          1708:         if (hostdata->last_message[2] == EXTENDED_SDTR) {
        !          1709:            /* sync. negotiation was rejected, setup asynchronous transfer with target */
        !          1710:            printk("\ntarget %d: rate=%d Mhz, asynchronous (sync. negotiation rejected)\n",
        !          1711:                   cmd->target,  DEF_CLK / DEF_STP);
        !          1712:            hostdata->sync_off[cmd->target] = 0;
        !          1713:            hostdata->sync_per[cmd->target] = DEF_STP; }
        !          1714:         break;
        !          1715:       case HEAD_OF_QUEUE_TAG:
        !          1716:       case ORDERED_QUEUE_TAG:
        !          1717:       case SIMPLE_QUEUE_TAG:
        !          1718:         cmd->device->tagged_queue = 0;
        !          1719:         hostdata->busy[cmd->target] |= (1 << cmd->lun);
        !          1720:         break;
        !          1721:       default:
        !          1722:         break;
        !          1723:       }
        !          1724:     if (hostdata->aborted) AM53C974_write_8(CMDREG, CMDREG_SATN);
        !          1725:     AM53C974_write_8(CMDREG, CMDREG_MA);
        !          1726:     break;
        !          1727:        
        !          1728:   case DISCONNECT:
        !          1729:     DEB_MSG(printk("scsi%d: disconnect message received; cmd %d for target %d, lun %d\n",
        !          1730:                   instance->host_no, cmd->cmnd[0], cmd->target, cmd->lun));
        !          1731:     cmd->device->disconnect = 1;
        !          1732:     hostdata->disconnecting = 1;
        !          1733:     AM53C974_write_8(CMDREG, CMDREG_MA); /* Accept message by clearing ACK */
        !          1734:     break;
        !          1735:                
        !          1736:   case SAVE_POINTERS:
        !          1737:   case RESTORE_POINTERS:
        !          1738:     DEB_MSG(printk("scsi%d: save/restore pointers message received; cmd %d for target %d, lun %d\n",
        !          1739:                   instance->host_no, cmd->cmnd[0], cmd->target, cmd->lun));
        !          1740:     /* The SCSI data pointer is *IMPLICITLY* saved on a disconnect
        !          1741:      * operation, in violation of the SCSI spec so we can safely 
        !          1742:      * ignore SAVE/RESTORE pointers calls.
        !          1743:      *
        !          1744:      * Unfortunately, some disks violate the SCSI spec and 
        !          1745:      * don't issue the required SAVE_POINTERS message before
        !          1746:      * disconnecting, and we have to break spec to remain 
        !          1747:      * compatible. */
        !          1748:     if (hostdata->aborted) {
        !          1749:        DEB_ABORT(printk("ATN set for cmnd %d upon reception of SAVE/REST. POINTERS message\n",
        !          1750:                          cmd->cmnd[0]));
        !          1751:        AM53C974_write_8(CMDREG, CMDREG_SATN); }
        !          1752:     AM53C974_write_8(CMDREG, CMDREG_MA);
        !          1753:     break;
        !          1754: 
        !          1755:   case EXTENDED_MESSAGE:
        !          1756:     DEB_MSG(printk("scsi%d: extended message received; cmd %d for target %d, lun %d\n",
        !          1757:                   instance->host_no, cmd->cmnd[0], cmd->target, cmd->lun));
        !          1758:    /* Extended messages are sent in the following format :
        !          1759:     * Byte     
        !          1760:     * 0                  EXTENDED_MESSAGE == 1
        !          1761:     * 1                  length (includes one byte for code, doesn't include first two bytes)
        !          1762:     * 2          code
        !          1763:     * 3..length+1 arguments
        !          1764:     */
        !          1765:    /* BEWARE!! THIS CODE IS EXTREMELY UGLY */
        !          1766:     extended_msg[0] = EXTENDED_MESSAGE;
        !          1767:     AM53C974_read_8(INSTREG) ; /* clear int */
        !          1768:     AM53C974_write_8(CMDREG, CMDREG_MA);  /* ack. msg byte, then wait for SO */  
        !          1769:     AM53C974_poll_int();
        !          1770:     /* get length */
        !          1771:     AM53C974_write_8(CMDREG, CMDREG_IT); 
        !          1772:     AM53C974_poll_int();
        !          1773:     AM53C974_write_8(CMDREG, CMDREG_MA);  /* ack. msg byte, then wait for SO */   
        !          1774:     AM53C974_poll_int();
        !          1775:     extended_msg[1] = len = AM53C974_read_8(FFREG); /* get length */
        !          1776:     p = extended_msg+2;
        !          1777:     /* read the remaining (len) bytes */
        !          1778:     while (len) {
        !          1779:       AM53C974_write_8(CMDREG, CMDREG_IT); 
        !          1780:       AM53C974_poll_int();
        !          1781:       if (len > 1) {
        !          1782:          AM53C974_write_8(CMDREG, CMDREG_MA);  /* ack. msg byte, then wait for SO */   
        !          1783:          AM53C974_poll_int(); }
        !          1784:       *p = AM53C974_read_8(FFREG);
        !          1785:       p++; len--; }
        !          1786: 
        !          1787: #ifdef AM53C974_DEBUG_MSG
        !          1788:     printk("scsi%d: received extended message: ", instance->host_no);
        !          1789:     for (j = 0; j < extended_msg[1] + 2; j++) {
        !          1790:         printk("0x%02x ", extended_msg[j]);
        !          1791:         if (j && !(j % 16)) printk("\n"); }
        !          1792:     printk("\n");
        !          1793: #endif
        !          1794: 
        !          1795:     /* check message */
        !          1796:     if (extended_msg[2] == EXTENDED_SDTR)
        !          1797:        ret = AM53C974_sync_neg(instance, cmd->target, extended_msg);
        !          1798:     if (ret || hostdata->aborted) AM53C974_write_8(CMDREG, CMDREG_SATN);
        !          1799: 
        !          1800:     AM53C974_write_8(CMDREG, CMDREG_MA); 
        !          1801:     break;
        !          1802: 
        !          1803:   default:
        !          1804:     printk("scsi%d: unknown message 0x%02x received\n",instance->host_no, msg);
        !          1805: #ifdef AM53C974_DEBUG
        !          1806:    deb_stop = 1;
        !          1807: #endif
        !          1808:     /* reject message */
        !          1809:     hostdata->msgout[0] = MESSAGE_REJECT; 
        !          1810:     AM53C974_write_8(CMDREG, CMDREG_SATN);
        !          1811:     AM53C974_write_8(CMDREG, CMDREG_MA);
        !          1812:     return(0);
        !          1813:     break;
        !          1814: 
        !          1815:   } /* switch (msg) */
        !          1816: KEYWAIT();
        !          1817: return(1);
        !          1818: }
        !          1819: 
        !          1820: /************************************************************************** 
        !          1821: * Function : AM53C974_select(struct Scsi_Host *instance, Scsi_Cmnd *cmd, int tag)
        !          1822: *
        !          1823: * Purpose : try to establish nexus for the command;
        !          1824: *           start sync negotiation via start stop and transfer the command in 
        !          1825: *           cmdout phase in case of an inquiry or req. sense command with no 
        !          1826: *           sync. neg. performed yet
        !          1827: *
        !          1828: * Inputs : instance -- which AM53C974
        !          1829: *          cmd -- command which requires the selection
        !          1830: *          tag -- tagged queueing
        !          1831: * 
        !          1832: * Returns : nothing
        !          1833: *        
        !          1834: * Note: this function initializes the selection process, which is continued 
        !          1835: *       in the interrupt handler
        !          1836: **************************************************************************/
        !          1837: static void AM53C974_select(struct Scsi_Host *instance, Scsi_Cmnd *cmd, int tag)
        !          1838: {
        !          1839: AM53C974_local_declare(); 
        !          1840: struct AM53C974_hostdata *hostdata = (struct AM53C974_hostdata *)instance->hostdata;
        !          1841: unsigned char            cfifo, tmp[3];
        !          1842: unsigned int             i, len, cmd_size = COMMAND_SIZE(cmd->cmnd[0]);
        !          1843: AM53C974_setio(instance);
        !          1844: 
        !          1845: cfifo = AM53C974_cfifo();
        !          1846: if (cfifo) {
        !          1847:    printk("scsi%d: select error; %d residual bytes in FIFO\n", instance->host_no, cfifo);
        !          1848:    AM53C974_write_8(CMDREG, CMDREG_CFIFO); /* clear FIFO */
        !          1849:    }                  
        !          1850: 
        !          1851: tmp[0] = IDENTIFY(1, cmd->lun);
        !          1852: 
        !          1853: #ifdef SCSI2
        !          1854: if (cmd->device->tagged_queue && (tag != TAG_NONE)) {
        !          1855:    tmp[1] = SIMPLE_QUEUE_TAG;
        !          1856:    if (tag == TAG_NEXT) {
        !          1857:       /* 0 is TAG_NONE, used to imply no tag for this command */
        !          1858:       if (cmd->device->current_tag == 0) cmd->device->current_tag = 1;
        !          1859:       cmd->tag = cmd->device->current_tag;
        !          1860:       cmd->device->current_tag++; }
        !          1861:      else  
        !          1862:       cmd->tag = (unsigned char)tag;
        !          1863:    tmp[2] = cmd->tag;
        !          1864:    hostdata->last_message[0] = SIMPLE_QUEUE_TAG;
        !          1865:    len = 3;
        !          1866:    AM53C974_write_8(FFREG, tmp[0]);
        !          1867:    AM53C974_write_8(FFREG, tmp[1]);
        !          1868:    AM53C974_write_8(FFREG, tmp[2]);
        !          1869:    }
        !          1870:   else
        !          1871: #endif /* def SCSI2 */
        !          1872:    {
        !          1873:    len = 1;
        !          1874:    AM53C974_write_8(FFREG, tmp[0]);
        !          1875:    cmd->tag = 0; }
        !          1876: 
        !          1877: /* in case of an inquiry or req. sense command with no sync. neg performed yet, we start
        !          1878:    sync negotiation via start stops and transfer the command in cmdout phase */
        !          1879: if (((cmd->cmnd[0] == INQUIRY) || (cmd->cmnd[0] == REQUEST_SENSE)) &&
        !          1880:     !(hostdata->sync_neg[cmd->target]) && hostdata->sync_en[cmd->target]) {
        !          1881:    hostdata->sync_neg[cmd->target] = 1;
        !          1882:    hostdata->msgout[0] = EXTENDED_MESSAGE;
        !          1883:    hostdata->msgout[1] = 3;
        !          1884:    hostdata->msgout[2] = EXTENDED_SDTR;
        !          1885:    hostdata->msgout[3] = 250 / (int)hostdata->max_rate[cmd->target];
        !          1886:    hostdata->msgout[4] = hostdata->max_offset[cmd->target];
        !          1887:    len += 5; }
        !          1888: 
        !          1889: AM53C974_write_8(SDIDREG, SDIREG_MASK & cmd->target);       /* setup dest. id  */
        !          1890: AM53C974_write_8(STIMREG, DEF_SCSI_TIMEOUT);                /* setup timeout reg */
        !          1891: switch (len) {
        !          1892:   case 1:
        !          1893:    for (i = 0; i < cmd_size; i++) AM53C974_write_8(FFREG, cmd->cmnd[i]);
        !          1894:    AM53C974_write_8(CMDREG, CMDREG_SAS);                    /* select with ATN, 1 msg byte */
        !          1895:    hostdata->msgout[0] = NOP;
        !          1896:    break;
        !          1897:   case 3:
        !          1898:    for (i = 0; i < cmd_size; i++) AM53C974_write_8(FFREG, cmd->cmnd[i]);
        !          1899:    AM53C974_write_8(CMDREG, CMDREG_SA3S);                   /* select with ATN, 3 msg bytes */
        !          1900:    hostdata->msgout[0] = NOP;
        !          1901:    break;
        !          1902:   default:
        !          1903:    AM53C974_write_8(CMDREG, CMDREG_SASS);   /* select with ATN, stop steps; continue in message out phase */
        !          1904:    break;
        !          1905:   }
        !          1906: }
        !          1907: 
        !          1908: /************************************************************************** 
        !          1909: * Function : AM53C974_intr_select(struct Scsi_Host *instance, unsigned char statreg)
        !          1910: *
        !          1911: * Purpose : handle reselection 
        !          1912: *
        !          1913: * Inputs : instance -- which AM53C974
        !          1914: *          statreg -- status register
        !          1915: * 
        !          1916: * Returns : nothing
        !          1917: *
        !          1918: * side effects: manipulates hostdata
        !          1919: **************************************************************************/
        !          1920: static void AM53C974_intr_reselect(struct Scsi_Host *instance, unsigned char statreg)
        !          1921: {
        !          1922: AM53C974_local_declare(); 
        !          1923: struct AM53C974_hostdata *hostdata = (struct AM53C974_hostdata *)instance->hostdata;
        !          1924: unsigned char            cfifo, msg[3], lun, t, target = 0;
        !          1925: #ifdef SCSI2
        !          1926:  unsigned                char tag;
        !          1927: #endif
        !          1928: Scsi_Cmnd                *tmp = NULL, *prev;
        !          1929: AM53C974_setio(instance);
        !          1930: 
        !          1931: cfifo = AM53C974_cfifo();
        !          1932: 
        !          1933: if (hostdata->selecting) {
        !          1934:    /* caught reselect interrupt in selection process;
        !          1935:       put selecting command back into the issue queue and continue with the
        !          1936:       reselecting command */
        !          1937:    DEB_RESEL(printk("AM53C974_intr_reselect: in selection process\n"));
        !          1938:    LIST(hostdata->sel_cmd, hostdata->issue_queue);
        !          1939:    hostdata->sel_cmd->host_scribble = (unsigned char *)hostdata->issue_queue;
        !          1940:    hostdata->issue_queue = hostdata->sel_cmd;
        !          1941:    hostdata->sel_cmd = NULL;
        !          1942:    hostdata->selecting = 0; }
        !          1943: 
        !          1944: /* 2 bytes must be in the FIFO now */
        !          1945: if (cfifo != 2) {
        !          1946:    printk("scsi %d: error: %d bytes in fifo, 2 expected\n", instance->host_no, cfifo);
        !          1947:    hostdata->aborted = 1;
        !          1948:    goto EXIT_ABORT; }
        !          1949: 
        !          1950: /* determine target which reselected */
        !          1951: t = AM53C974_read_8(FFREG);
        !          1952: if (!(t & (1 << instance->this_id))) {
        !          1953:    printk("scsi %d: error: invalid host id\n", instance->host_no);
        !          1954:    hostdata->aborted = 1;
        !          1955:    goto EXIT_ABORT; }
        !          1956: t ^= (1 << instance->this_id);
        !          1957: target = 0; while (t != 1) { t >>= 1; target++; }
        !          1958: DEB_RESEL(printk("scsi %d: reselect; target: %d\n", instance->host_no, target));
        !          1959:       
        !          1960: if (hostdata->aborted) goto EXIT_ABORT;
        !          1961: 
        !          1962: if ((statreg & STATREG_PHASE) != PHASE_MSGIN) {
        !          1963:    printk("scsi %d: error: upon reselection interrupt not in MSGIN\n", instance->host_no);
        !          1964:    hostdata->aborted = 1;
        !          1965:    goto EXIT_ABORT; }
        !          1966: 
        !          1967: msg[0] = AM53C974_read_8(FFREG);
        !          1968: if (!msg[0] & 0x80) {
        !          1969:    printk("scsi%d: error: expecting IDENTIFY message, got ", instance->host_no);
        !          1970:    print_msg(msg);
        !          1971:    hostdata->aborted = 1;
        !          1972:    goto EXIT_ABORT; }
        !          1973: 
        !          1974: lun = (msg[0] & 0x07);
        !          1975: 
        !          1976: /* We need to add code for SCSI-II to track which devices have
        !          1977:  * I_T_L_Q nexuses established, and which have simple I_T_L
        !          1978:  * nexuses so we can chose to do additional data transfer. */
        !          1979: #ifdef SCSI2
        !          1980: #error "SCSI-II tagged queueing is not supported yet"
        !          1981: #endif
        !          1982: 
        !          1983: /* Find the command corresponding to the I_T_L or I_T_L_Q  nexus we 
        !          1984:  * just reestablished, and remove it from the disconnected queue. */
        !          1985: for (tmp = (Scsi_Cmnd *)hostdata->disconnected_queue, prev = NULL; 
        !          1986:      tmp; prev = tmp, tmp = (Scsi_Cmnd *)tmp->host_scribble) 
        !          1987:     if ((target == tmp->target) && (lun == tmp->lun) 
        !          1988: #ifdef SCSI2
        !          1989:          && (tag == tmp->tag) 
        !          1990: #endif
        !          1991:        ) {
        !          1992:        if (prev) {
        !          1993:          REMOVE(prev, (Scsi_Cmnd *)(prev->host_scribble), tmp,
        !          1994:                  (Scsi_Cmnd *)(tmp->host_scribble));
        !          1995:          prev->host_scribble = tmp->host_scribble; } 
        !          1996:          else {
        !          1997:          REMOVE(-1, hostdata->disconnected_queue, tmp, tmp->host_scribble);
        !          1998:          hostdata->disconnected_queue = (Scsi_Cmnd *)tmp->host_scribble; }
        !          1999:        tmp->host_scribble = NULL;
        !          2000:        hostdata->connected = tmp;
        !          2001:        break; }
        !          2002: 
        !          2003: if (!tmp) {
        !          2004: #ifdef SCSI2
        !          2005:    printk("scsi%d: warning : target %d lun %d tag %d not in disconnect_queue.\n",
        !          2006:          instance->host_no, target, lun, tag);
        !          2007: #else
        !          2008:    printk("scsi%d: warning : target %d lun %d not in disconnect_queue.\n",
        !          2009:          instance->host_no, target, lun);
        !          2010: #endif
        !          2011:    /* Since we have an established nexus that we can't do anything with, we must abort it. */
        !          2012:    hostdata->aborted = 1;
        !          2013:    DEB(AM53C974_keywait());
        !          2014:    goto EXIT_ABORT; }
        !          2015:   else
        !          2016:    goto EXIT_OK;
        !          2017: 
        !          2018: EXIT_ABORT: 
        !          2019: AM53C974_write_8(CMDREG, CMDREG_SATN);
        !          2020: AM53C974_write_8(CMDREG, CMDREG_MA);
        !          2021: return;
        !          2022: 
        !          2023: EXIT_OK:
        !          2024: DEB_RESEL(printk("scsi%d: nexus established, target = %d, lun = %d, tag = %d\n",
        !          2025:          instance->host_no, target, tmp->lun, tmp->tag));
        !          2026: AM53C974_set_sync(instance, target);
        !          2027: AM53C974_write_8(SDIDREG, SDIREG_MASK & target);       /* setup dest. id  */
        !          2028: AM53C974_write_8(CMDREG, CMDREG_MA);
        !          2029: hostdata->dma_busy = 0;
        !          2030: hostdata->connected->SCp.phase = PHASE_CMDOUT;
        !          2031: }
        !          2032: 
        !          2033: /************************************************************************** 
        !          2034: * Function : AM53C974_transfer_dma(struct Scsi_Host *instance, short dir,
        !          2035: *                                  unsigned long length, char *data)
        !          2036: *
        !          2037: * Purpose : setup DMA transfer
        !          2038: *
        !          2039: * Inputs : instance -- which AM53C974
        !          2040: *          dir -- direction flag, 0: write to device, read from memory; 
        !          2041: *                                 1: read from device, write to memory
        !          2042: *          length -- number of bytes to transfer to from buffer
        !          2043: *          data -- pointer to data buffer
        !          2044: * 
        !          2045: * Returns : nothing
        !          2046: **************************************************************************/
        !          2047: static __inline__ void AM53C974_transfer_dma(struct Scsi_Host *instance, short dir,
        !          2048:                                              unsigned long length, char *data)
        !          2049: {
        !          2050: AM53C974_local_declare();
        !          2051: AM53C974_setio(instance);
        !          2052: 
        !          2053: AM53C974_write_8(CMDREG, CMDREG_NOP);
        !          2054: AM53C974_write_8(DMACMD, (dir << 7) | DMACMD_INTE_D);  /* idle command */
        !          2055: AM53C974_write_8(STCLREG, (unsigned char)(length & 0xff));
        !          2056: AM53C974_write_8(STCMREG, (unsigned char)((length & 0xff00) >> 8));
        !          2057: AM53C974_write_8(STCHREG, (unsigned char)((length & 0xff0000) >> 16));
        !          2058: AM53C974_write_32(DMASTC, length & 0xffffff);
        !          2059: AM53C974_write_32(DMASPA, virt_to_bus(data));
        !          2060: AM53C974_write_8(CMDREG, CMDREG_IT | CMDREG_DMA);
        !          2061: AM53C974_write_8(DMACMD, (dir << 7) | DMACMD_INTE_D | DMACMD_START);
        !          2062: }
        !          2063: 
        !          2064: /************************************************************************** 
        !          2065: * Function : AM53C974_dma_blast(struct Scsi_Host *instance, unsigned char dmastatus,
        !          2066: *                               unsigned char statreg)
        !          2067: *
        !          2068: * Purpose : cleanup DMA transfer
        !          2069: *
        !          2070: * Inputs : instance -- which AM53C974
        !          2071: *          dmastatus -- dma status register
        !          2072: *          statreg -- status register
        !          2073: * 
        !          2074: * Returns : nothing
        !          2075: **************************************************************************/
        !          2076: static void AM53C974_dma_blast(struct Scsi_Host *instance, unsigned char dmastatus,
        !          2077:                                unsigned char statreg)
        !          2078: {
        !          2079: AM53C974_local_declare();
        !          2080: struct AM53C974_hostdata *hostdata = (struct AM53C974_hostdata *)instance->hostdata;
        !          2081: unsigned long            ctcreg;
        !          2082: int                      dir = statreg & STATREG_IO;
        !          2083: int                      cfifo, pio, i = 0;
        !          2084: AM53C974_setio(instance);
        !          2085: 
        !          2086: do {
        !          2087:    cfifo = AM53C974_cfifo();
        !          2088:    i++;
        !          2089:    } while (cfifo && (i < 50000));
        !          2090: pio = (i == 50000) ? 1: 0;
        !          2091: 
        !          2092: if (statreg & STATREG_CTZ) { AM53C974_write_8(DMACMD, DMACMD_IDLE); return; }
        !          2093: 
        !          2094: if (dmastatus & DMASTATUS_DONE) { AM53C974_write_8(DMACMD, DMACMD_IDLE); return; }
        !          2095: 
        !          2096: AM53C974_write_8(DMACMD, ((dir << 7) & DMACMD_DIR) | DMACMD_BLAST);
        !          2097: while(!(AM53C974_read_8(DMASTATUS) & DMASTATUS_BCMPLT)) ;
        !          2098: AM53C974_write_8(DMACMD, DMACMD_IDLE);
        !          2099: 
        !          2100: if (pio) {
        !          2101:    /* transfer residual bytes via PIO */
        !          2102:    unsigned char *wac = (unsigned char *)AM53C974_read_32(DMAWAC);
        !          2103:    printk("pio mode, residual=%d\n", AM53C974_read_8(CFIREG) & CFIREG_CF);
        !          2104:    while (AM53C974_read_8(CFIREG) & CFIREG_CF) *(wac++) = AM53C974_read_8(FFREG);
        !          2105:    }
        !          2106: 
        !          2107: ctcreg = AM53C974_read_8(CTCLREG) | (AM53C974_read_8(CTCMREG) << 8) |
        !          2108:          (AM53C974_read_8(CTCHREG) << 16);
        !          2109: 
        !          2110: hostdata->connected->SCp.ptr += hostdata->connected->SCp.this_residual - ctcreg;
        !          2111: hostdata->connected->SCp.this_residual = ctcreg;
        !          2112: }
        !          2113: 
        !          2114: /************************************************************************** 
        !          2115: * Function : AM53C974_intr_bus_reset(struct Scsi_Host *instance)
        !          2116: *
        !          2117: * Purpose : handle bus reset interrupt
        !          2118: *
        !          2119: * Inputs : instance -- which AM53C974
        !          2120: * 
        !          2121: * Returns : nothing
        !          2122: **************************************************************************/
        !          2123: static void AM53C974_intr_bus_reset(struct Scsi_Host *instance)
        !          2124: {
        !          2125: AM53C974_local_declare();
        !          2126: unsigned char cntlreg1;
        !          2127: AM53C974_setio(instance);
        !          2128: 
        !          2129: AM53C974_write_8(CMDREG, CMDREG_CFIFO);
        !          2130: AM53C974_write_8(CMDREG, CMDREG_NOP);
        !          2131: 
        !          2132: cntlreg1 = AM53C974_read_8(CNTLREG1);
        !          2133: AM53C974_write_8(CNTLREG1, cntlreg1 | CNTLREG1_DISR);
        !          2134: }
        !          2135: 
        !          2136: /**************************************************************************
        !          2137: * Function : int AM53C974_abort(Scsi_Cmnd *cmd)
        !          2138: *
        !          2139: * Purpose : abort a command
        !          2140: *
        !          2141: * Inputs : cmd - the Scsi_Cmnd to abort, code - code to set the 
        !          2142: *      host byte of the result field to, if zero DID_ABORTED is 
        !          2143: *      used.
        !          2144: *
        !          2145: * Returns : 0 - success, -1 on failure.
        !          2146:  **************************************************************************/
        !          2147: int AM53C974_abort(Scsi_Cmnd *cmd)
        !          2148: {
        !          2149: AM53C974_local_declare();
        !          2150: struct Scsi_Host         *instance = cmd->host;
        !          2151: struct AM53C974_hostdata *hostdata = (struct AM53C974_hostdata *)instance->hostdata;
        !          2152: Scsi_Cmnd                *tmp, **prev;
        !          2153: 
        !          2154: #ifdef AM53C974_DEBUG
        !          2155:    deb_stop = 1;
        !          2156: #endif
        !          2157: cli();
        !          2158: AM53C974_setio(instance);
        !          2159: 
        !          2160: DEB_ABORT(printk(SEPARATOR_LINE));
        !          2161: DEB_ABORT(printk("scsi%d : AM53C974_abort called -- trouble starts!!\n", instance->host_no));
        !          2162: DEB_ABORT(AM53C974_print(instance));
        !          2163: DEB_ABORT(AM53C974_keywait());
        !          2164: 
        !          2165: /* Case 1 : If the command is the currently executing command, 
        !          2166:             we'll set the aborted flag and return control so that the
        !          2167:             information transfer routine can exit cleanly. */
        !          2168: if ((hostdata->connected == cmd) || (hostdata->sel_cmd == cmd)) {
        !          2169:    DEB_ABORT(printk("scsi%d: aborting connected command\n", instance->host_no));
        !          2170:    hostdata->aborted = 1;
        !          2171:    hostdata->msgout[0] = ABORT;
        !          2172:    sti();
        !          2173:    return(SCSI_ABORT_PENDING); }
        !          2174: 
        !          2175: /* Case 2 : If the command hasn't been issued yet,
        !          2176:             we simply remove it from the issue queue. */
        !          2177: for (prev = (Scsi_Cmnd **)&(hostdata->issue_queue), 
        !          2178:      tmp = (Scsi_Cmnd *)hostdata->issue_queue; tmp; 
        !          2179:      prev = (Scsi_Cmnd **)&(tmp->host_scribble),
        !          2180:      tmp = (Scsi_Cmnd *)tmp->host_scribble) {
        !          2181:     if (cmd == tmp) {
        !          2182:        DEB_ABORT(printk("scsi%d : abort removed command from issue queue.\n", instance->host_no));
        !          2183:        REMOVE(5, *prev, tmp, tmp->host_scribble);
        !          2184:        (*prev) = (Scsi_Cmnd *)tmp->host_scribble;
        !          2185:        tmp->host_scribble = NULL;
        !          2186:        tmp->result = DID_ABORT << 16;
        !          2187:        sti();
        !          2188:        tmp->done(tmp);
        !          2189:        return(SCSI_ABORT_SUCCESS); }
        !          2190: #ifdef AM53C974_DEBUG_ABORT
        !          2191:       else {
        !          2192:        if (prev == (Scsi_Cmnd **)tmp) 
        !          2193:           printk("scsi%d : LOOP\n", instance->host_no); 
        !          2194:        }
        !          2195: #endif
        !          2196:     }
        !          2197:  
        !          2198: /* Case 3 : If any commands are connected, we're going to fail the abort
        !          2199:  *         and let the high level SCSI driver retry at a later time or 
        !          2200:  *         issue a reset.
        !          2201:  *
        !          2202:  *         Timeouts, and therefore aborted commands, will be highly unlikely
        !          2203:  *          and handling them cleanly in this situation would make the common
        !          2204:  *         case of noresets less efficient, and would pollute our code.  So,
        !          2205:  *         we fail. */
        !          2206: if (hostdata->connected || hostdata->sel_cmd) {
        !          2207:    DEB_ABORT(printk("scsi%d : abort failed, other command connected.\n", instance->host_no));
        !          2208:    sti();
        !          2209:    return(SCSI_ABORT_NOT_RUNNING); }
        !          2210: 
        !          2211: /* Case 4: If the command is currently disconnected from the bus, and 
        !          2212:  *        there are no connected commands, we reconnect the I_T_L or 
        !          2213:  *        I_T_L_Q nexus associated with it, go into message out, and send 
        !          2214:  *         an abort message. */
        !          2215: for (tmp = (Scsi_Cmnd *)hostdata->disconnected_queue; tmp; 
        !          2216:      tmp = (Scsi_Cmnd *)tmp->host_scribble) {
        !          2217:      if (cmd == tmp) {
        !          2218:         DEB_ABORT(printk("scsi%d: aborting disconnected command\n", instance->host_no));
        !          2219:         hostdata->aborted = 1;
        !          2220:         hostdata->msgout[0] = ABORT;
        !          2221:         hostdata->selecting = 1;
        !          2222:         hostdata->sel_cmd = tmp;
        !          2223:         AM53C974_write_8(CMDREG, CMDREG_DSR);
        !          2224:         sti();
        !          2225:         return(SCSI_ABORT_PENDING); }
        !          2226:      }
        !          2227: 
        !          2228: /* Case 5 : If we reached this point, the command was not found in any of 
        !          2229:  *         the queues.
        !          2230:  *
        !          2231:  * We probably reached this point because of an unlikely race condition
        !          2232:  * between the command completing successfully and the abortion code,
        !          2233:  * so we won't panic, but we will notify the user in case something really
        !          2234:  * broke. */
        !          2235: DEB_ABORT(printk("scsi%d : abort failed, command not found.\n", instance->host_no));
        !          2236: sti();
        !          2237: return(SCSI_ABORT_NOT_RUNNING);
        !          2238: }
        !          2239: 
        !          2240: /************************************************************************** 
        !          2241: * Function : int AM53C974_reset(Scsi_Cmnd *cmd)
        !          2242: *
        !          2243: * Purpose : reset the SCSI controller and bus
        !          2244: *
        !          2245: * Inputs : cmd -- which command within the command block was responsible for the reset
        !          2246: * 
        !          2247: * Returns : status (SCSI_ABORT_SUCCESS)
        !          2248: **************************************************************************/
        !          2249: int AM53C974_reset(Scsi_Cmnd *cmd, unsigned int flags)
        !          2250: {
        !          2251: AM53C974_local_declare();
        !          2252: int                      i;
        !          2253: struct Scsi_Host         *instance = cmd->host;
        !          2254: struct AM53C974_hostdata *hostdata = (struct AM53C974_hostdata *)instance->hostdata;
        !          2255: AM53C974_setio(instance);
        !          2256: 
        !          2257: cli();
        !          2258: DEB(printk("AM53C974_reset called; "));
        !          2259: 
        !          2260: printk("AM53C974_reset called\n");
        !          2261: AM53C974_print(instance);
        !          2262: AM53C974_keywait();
        !          2263: 
        !          2264: /* do hard reset */
        !          2265: AM53C974_write_8(CMDREG, CMDREG_RDEV);
        !          2266: AM53C974_write_8(CMDREG, CMDREG_NOP);
        !          2267: hostdata->msgout[0] = NOP;
        !          2268: for (i = 0; i < 8; i++) {
        !          2269:     hostdata->busy[i] = 0;
        !          2270:     hostdata->sync_per[i] = DEF_STP;
        !          2271:     hostdata->sync_off[i] = 0;
        !          2272:     hostdata->sync_neg[i] = 0; }
        !          2273: hostdata->last_message[0] = NOP;
        !          2274: hostdata->sel_cmd = NULL;
        !          2275: hostdata->connected = NULL;
        !          2276: hostdata->issue_queue = NULL;
        !          2277: hostdata->disconnected_queue = NULL;
        !          2278: hostdata->in_reset = 0;
        !          2279: hostdata->aborted = 0;
        !          2280: hostdata->selecting = 0;
        !          2281: hostdata->disconnecting = 0;
        !          2282: hostdata->dma_busy = 0;
        !          2283: 
        !          2284: /* reset bus */
        !          2285: AM53C974_write_8(CNTLREG1, CNTLREG1_DISR | instance->this_id); /* disable interrupt upon SCSI RESET */
        !          2286: AM53C974_write_8(CMDREG, CMDREG_RBUS);     /* reset SCSI bus */
        !          2287: udelay(40);
        !          2288: AM53C974_config_after_reset(instance);
        !          2289: 
        !          2290: sti();
        !          2291: cmd->result = DID_RESET << 16;
        !          2292: cmd->scsi_done(cmd);
        !          2293: return SCSI_ABORT_SUCCESS;
        !          2294: }
        !          2295: 
        !          2296: 
        !          2297: /*
        !          2298:  * AM53C974_release()
        !          2299:  *
        !          2300:  * Release resources allocated for a single AM53C974 adapter.
        !          2301:  */
        !          2302: int
        !          2303: AM53C974_release(struct Scsi_Host *shp)
        !          2304: {
        !          2305:        free_irq(shp->irq, NULL);
        !          2306:        scsi_unregister(shp);
        !          2307:        return 0;
        !          2308: }
        !          2309: 
        !          2310: 
        !          2311: #ifdef MODULE
        !          2312: /* Eventually this will go into an include file, but this will be later */
        !          2313: Scsi_Host_Template driver_template = AM53C974;
        !          2314: 
        !          2315: #include "scsi_module.c"
        !          2316: #endif

unix.superglobalmegacorp.com

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