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

1.1     ! root        1: #ifndef NDEBUG
        !             2: #define NDEBUG (NDEBUG_RESTART_SELECT | NDEBUG_ABORT)
        !             3: #endif
        !             4: /* 
        !             5:  * NCR 5380 generic driver routines.  These should make it *trivial*
        !             6:  *     to implement 5380 SCSI drivers under Linux with a non-trantor
        !             7:  *     architecture.
        !             8:  *
        !             9:  *     Note that these routines also work with NR53c400 family chips.
        !            10:  *
        !            11:  * Copyright 1993, Drew Eckhardt
        !            12:  *     Visionary Computing 
        !            13:  *     (Unix and Linux consulting and custom programming)
        !            14:  *     [email protected]
        !            15:  *     +1 (303) 666-5836
        !            16:  *
        !            17:  * DISTRIBUTION RELEASE 6. 
        !            18:  *
        !            19:  * For more information, please consult 
        !            20:  *
        !            21:  * NCR 5380 Family
        !            22:  * SCSI Protocol Controller
        !            23:  * Databook
        !            24:  *
        !            25:  * NCR Microelectronics
        !            26:  * 1635 Aeroplaza Drive
        !            27:  * Colorado Springs, CO 80916
        !            28:  * 1+ (719) 578-3400
        !            29:  * 1+ (800) 334-5454
        !            30:  */
        !            31: 
        !            32: /*
        !            33:  * $Log: NCR5380.c,v $
        !            34:  * Revision 1.1  1999/04/26 05:53:59  tb
        !            35:  * 1998-11-30  OKUJI Yoshinori  <[email protected]>
        !            36:  *
        !            37:  *     Clean up linux emulation code to make it architecture-independent
        !            38:  *     as much as possible.
        !            39:  *
        !            40:  *     * linux: Renamed from linuxdev.
        !            41:  *     * Makefile.in (objfiles): Add linux.o instead of linuxdev.o.
        !            42:  *     (MAKE): New variable. Used for the linux.o target.
        !            43:  *     * configure.in: Add AC_CHECK_TOOL(MAKE, make).
        !            44:  *     * i386/i386/spl.h: Include <i386/ipl.h>, for compatibility with
        !            45:  *     OSF Mach 3.0. Suggested by Elgin Lee <[email protected]>.
        !            46:  *     * linux/src: Renamed from linux/linux.
        !            47:  *     * linux/dev: Renamed from linux/mach.
        !            48:  *     * linux/Drivers.in (AC_INIT): Use dev/include/linux/autoconf.h,
        !            49:  *     instead of mach/include/linux/autoconf.h.
        !            50:  *     * Makefile.in (all): Target ../linux.o instead of ../linuxdev.o.
        !            51:  *     * linux/dev/drivers/block/genhd.c: Include <machine/spl.h> instead
        !            52:  *     of <i386/ipl.h>.
        !            53:  *     * linux/dev/drivers/net/auto_irq.c: Remove unneeded header files,
        !            54:  *     <i386/ipl.h> and <i386/pic.h>.
        !            55:  *     * linux/dev/init/main.c: Many i386-dependent codes moved to ...
        !            56:  *     * linux/dev/arch/i386/irq.c: ... here.
        !            57:  *     * linux/dev/arch/i386/setup.c: New file.
        !            58:  *     * linux/dev/arch/i386/linux_emul.h: Likewise.
        !            59:  *     * linux/dev/arch/i386/glue/timer.c: Merged into sched.c.
        !            60:  *     * linux/dev/arch/i386/glue/sched.c: Include <machine/spl.h> instead
        !            61:  *     of <i386/ipl.h>, and moved to ...
        !            62:  *     * linux/dev/kernel/sched.c: ... here.
        !            63:  *     * linux/dev/arch/i386/glue/block.c: Include <machine/spl.h> and
        !            64:  *     <linux_emul.h>, instead of i386-dependent header files, and
        !            65:  *     moved to ...
        !            66:  *     * linux/dev/glue/blocl.c: ... here.
        !            67:  *     * linux/dev/arch/i386/glue/net.c: Include <machine/spl.h> and
        !            68:  *     <linux_emul.h>, instead of i386-dependent header files, and
        !            69:  *     moved to ...
        !            70:  *     * linux/dev/glue/net.c: ... here.
        !            71:  *     * linux/dev/arch/i386/glue/misc.c: Remove `x86' and moved to ...
        !            72:  *     * linux/dev/glue/misc.c: ... here.
        !            73:  *     * linux/dev/arch/i386/glue/kmem.c: Moved to ...
        !            74:  *     * linux/dev/glue/kmem.c: ... here.
        !            75:  *
        !            76:  * Revision 1.7  1996/3/2      Ray Van Tassle ([email protected])
        !            77:  * added proc_info
        !            78:  * added support needed for DTC 3180/3280
        !            79:  * fixed a couple of bugs
        !            80:  *
        !            81: 
        !            82:  * Revision 1.5  1994/01/19  09:14:57  drew
        !            83:  * Fixed udelay() hack that was being used on DATAOUT phases
        !            84:  * instead of a proper wait for the final handshake.
        !            85:  *
        !            86:  * Revision 1.4  1994/01/19  06:44:25  drew
        !            87:  * *** empty log message ***
        !            88:  *
        !            89:  * Revision 1.3  1994/01/19  05:24:40  drew
        !            90:  * Added support for TCR LAST_BYTE_SENT bit.
        !            91:  *
        !            92:  * Revision 1.2  1994/01/15  06:14:11  drew
        !            93:  * REAL DMA support, bug fixes.
        !            94:  *
        !            95:  * Revision 1.1  1994/01/15  06:00:54  drew
        !            96:  * Initial revision
        !            97:  *
        !            98:  */
        !            99: 
        !           100: /*
        !           101:  * Further development / testing that should be done : 
        !           102:  * 1.  Cleanup the NCR5380_transfer_dma function and DMA operation complete
        !           103:  *     code so that everything does the same thing that's done at the 
        !           104:  *     end of a pseudo-DMA read operation.
        !           105:  *
        !           106:  * 2.  Fix REAL_DMA (interrupt driven, polled works fine) -
        !           107:  *     basically, transfer size needs to be reduced by one 
        !           108:  *     and the last byte read as is done with PSEUDO_DMA.
        !           109:  * 
        !           110:  * 3.  Test USLEEP code 
        !           111:  *
        !           112:  * 4.  Test SCSI-II tagged queueing (I have no devices which support 
        !           113:  *     tagged queueing)
        !           114:  *
        !           115:  * 5.  Test linked command handling code after Eric is ready with 
        !           116:  *      the high level code.
        !           117:  */
        !           118: 
        !           119: #if (NDEBUG & NDEBUG_LISTS)
        !           120: #define LIST(x,y) {printk("LINE:%d   Adding %p to %p\n", __LINE__, (void*)(x), (void*)(y)); if ((x)==(y)) udelay(5); }
        !           121: #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); }
        !           122: #else
        !           123: #define LIST(x,y)
        !           124: #define REMOVE(w,x,y,z)
        !           125: #endif
        !           126: 
        !           127: #ifndef notyet
        !           128: #undef LINKED
        !           129: #undef USLEEP
        !           130: #undef REAL_DMA
        !           131: #endif
        !           132: 
        !           133: #ifdef REAL_DMA_POLL
        !           134: #undef READ_OVERRUNS
        !           135: #define READ_OVERRUNS
        !           136: #endif
        !           137: 
        !           138: /*
        !           139:  * Design
        !           140:  * Issues :
        !           141:  *
        !           142:  * The other Linux SCSI drivers were written when Linux was Intel PC-only,
        !           143:  * and specifically for each board rather than each chip.  This makes their
        !           144:  * adaptation to platforms like the Mac (Some of which use NCR5380's)
        !           145:  * more difficult than it has to be.
        !           146:  *
        !           147:  * Also, many of the SCSI drivers were written before the command queuing
        !           148:  * routines were implemented, meaning their implementations of queued 
        !           149:  * commands were hacked on rather than designed in from the start.
        !           150:  *
        !           151:  * When I designed the Linux SCSI drivers I figured that 
        !           152:  * while having two different SCSI boards in a system might be useful
        !           153:  * for debugging things, two of the same type wouldn't be used.
        !           154:  * Well, I was wrong and a number of users have mailed me about running
        !           155:  * multiple high-performance SCSI boards in a server.
        !           156:  *
        !           157:  * Finally, when I get questions from users, I have no idea what 
        !           158:  * revision of my driver they are running.
        !           159:  *
        !           160:  * This driver attempts to address these problems :
        !           161:  * This is a generic 5380 driver.  To use it on a different platform, 
        !           162:  * one simply writes appropriate system specific macros (ie, data
        !           163:  * transfer - some PC's will use the I/O bus, 68K's must use 
        !           164:  * memory mapped) and drops this file in their 'C' wrapper.
        !           165:  *
        !           166:  * As far as command queueing, two queues are maintained for 
        !           167:  * each 5380 in the system - commands that haven't been issued yet,
        !           168:  * and commands that are currently executing.  This means that an 
        !           169:  * unlimited number of commands may be queued, letting 
        !           170:  * more commands propagate from the higher driver levels giving higher 
        !           171:  * throughput.  Note that both I_T_L and I_T_L_Q nexuses are supported, 
        !           172:  * allowing multiple commands to propagate all the way to a SCSI-II device 
        !           173:  * while a command is already executing.
        !           174:  *
        !           175:  * To solve the multiple-boards-in-the-same-system problem, 
        !           176:  * there is a separate instance structure for each instance
        !           177:  * of a 5380 in the system.  So, multiple NCR5380 drivers will
        !           178:  * be able to coexist with appropriate changes to the high level
        !           179:  * SCSI code.  
        !           180:  *
        !           181:  * A NCR5380_PUBLIC_REVISION macro is provided, with the release
        !           182:  * number (updated for each public release) printed by the 
        !           183:  * NCR5380_print_options command, which should be called from the 
        !           184:  * wrapper detect function, so that I know what release of the driver
        !           185:  * users are using.
        !           186:  *
        !           187:  * Issues specific to the NCR5380 : 
        !           188:  *
        !           189:  * When used in a PIO or pseudo-dma mode, the NCR5380 is a braindead 
        !           190:  * piece of hardware that requires you to sit in a loop polling for 
        !           191:  * the REQ signal as long as you are connected.  Some devices are 
        !           192:  * brain dead (ie, many TEXEL CD ROM drives) and won't disconnect 
        !           193:  * while doing long seek operations.
        !           194:  * 
        !           195:  * The workaround for this is to keep track of devices that have
        !           196:  * disconnected.  If the device hasn't disconnected, for commands that
        !           197:  * should disconnect, we do something like 
        !           198:  *
        !           199:  * while (!REQ is asserted) { sleep for N usecs; poll for M usecs }
        !           200:  * 
        !           201:  * Some tweaking of N and M needs to be done.  An algorithm based 
        !           202:  * on "time to data" would give the best results as long as short time
        !           203:  * to datas (ie, on the same track) were considered, however these 
        !           204:  * broken devices are the exception rather than the rule and I'd rather
        !           205:  * spend my time optimizing for the normal case.
        !           206:  *
        !           207:  * Architecture :
        !           208:  *
        !           209:  * At the heart of the design is a coroutine, NCR5380_main,
        !           210:  * which is started when not running by the interrupt handler,
        !           211:  * timer, and queue command function.  It attempts to establish
        !           212:  * I_T_L or I_T_L_Q nexuses by removing the commands from the 
        !           213:  * issue queue and calling NCR5380_select() if a nexus 
        !           214:  * is not established. 
        !           215:  *
        !           216:  * Once a nexus is established, the NCR5380_information_transfer()
        !           217:  * phase goes through the various phases as instructed by the target.
        !           218:  * if the target goes into MSG IN and sends a DISCONNECT message,
        !           219:  * the command structure is placed into the per instance disconnected
        !           220:  * queue, and NCR5380_main tries to find more work.  If USLEEP
        !           221:  * was defined, and the target is idle for too long, the system
        !           222:  * will try to sleep.
        !           223:  *
        !           224:  * If a command has disconnected, eventually an interrupt will trigger,
        !           225:  * calling NCR5380_intr()  which will in turn call NCR5380_reselect
        !           226:  * to reestablish a nexus.  This will run main if necessary.
        !           227:  *
        !           228:  * On command termination, the done function will be called as 
        !           229:  * appropriate.
        !           230:  *
        !           231:  * SCSI pointers are maintained in the SCp field of SCSI command 
        !           232:  * structures, being initialized after the command is connected
        !           233:  * in NCR5380_select, and set as appropriate in NCR5380_information_transfer.
        !           234:  * Note that in violation of the standard, an implicit SAVE POINTERS operation
        !           235:  * is done, since some BROKEN disks fail to issue an explicit SAVE POINTERS.
        !           236:  */
        !           237: 
        !           238: /*
        !           239:  * Using this file :
        !           240:  * This file a skeleton Linux SCSI driver for the NCR 5380 series
        !           241:  * of chips.  To use it, you write a architecture specific functions 
        !           242:  * and macros and include this file in your driver.
        !           243:  *
        !           244:  * These macros control options : 
        !           245:  * AUTOPROBE_IRQ - if defined, the NCR5380_probe_irq() function will be 
        !           246:  *     defined.
        !           247:  * 
        !           248:  * AUTOSENSE - if defined, REQUEST SENSE will be performed automatically
        !           249:  *     for commands that return with a CHECK CONDITION status. 
        !           250:  *
        !           251:  * DIFFERENTIAL - if defined, NCR53c81 chips will use external differential
        !           252:  *     transceivers. 
        !           253:  *
        !           254:  * DONT_USE_INTR - if defined, never use interrupts, even if we probe or
        !           255:  *     override-configure an IRQ.
        !           256:  *
        !           257:  * LIMIT_TRANSFERSIZE - if defined, limit the pseudo-dma transfers to 512
        !           258:  *     bytes at a time.  Since interrupts are disabled by default during
        !           259:  *     these transfers, we might need this to give reasonable interrupt
        !           260:  *     service time if the transfer size gets too large.
        !           261:  *
        !           262:  * LINKED - if defined, linked commands are supported.
        !           263:  *
        !           264:  * PSEUDO_DMA - if defined, PSEUDO DMA is used during the data transfer phases.
        !           265:  *
        !           266:  * REAL_DMA - if defined, REAL DMA is used during the data transfer phases.
        !           267:  *
        !           268:  * REAL_DMA_POLL - if defined, REAL DMA is used but the driver doesn't
        !           269:  *     rely on phase mismatch and EOP interrupts to determine end 
        !           270:  *     of phase.
        !           271:  *
        !           272:  * SCSI2 - if defined, SCSI-2 tagged queuing is used where possible
        !           273:  *
        !           274:  * UNSAFE - leave interrupts enabled during pseudo-DMA transfers.  You
        !           275:  *         only really want to use this if you're having a problem with
        !           276:  *         dropped characters during high speed communications, and even
        !           277:  *         then, you're going to be better off twiddling with transfersize
        !           278:  *         in the high level code.
        !           279:  *
        !           280:  * USLEEP - if defined, on devices that aren't disconnecting from the 
        !           281:  *     bus, we will go to sleep so that the CPU can get real work done 
        !           282:  *     when we run a command that won't complete immediately.
        !           283:  *
        !           284:  * Note that if USLEEP is defined, NCR5380_TIMER *must* also be
        !           285:  * defined.
        !           286:  *
        !           287:  * Defaults for these will be provided if USLEEP is defined, although
        !           288:  * the user may want to adjust these to allocate CPU resources to 
        !           289:  * the SCSI driver or "real" code.
        !           290:  * 
        !           291:  * USLEEP_SLEEP - amount of time, in jiffies, to sleep
        !           292:  *
        !           293:  * USLEEP_POLL - amount of time, in jiffies, to poll
        !           294:  *
        !           295:  * These macros MUST be defined :
        !           296:  * NCR5380_local_declare() - declare any local variables needed for your
        !           297:  *     transfer routines.
        !           298:  *
        !           299:  * NCR5380_setup(instance) - initialize any local variables needed from a given
        !           300:  *     instance of the host adapter for NCR5380_{read,write,pread,pwrite}
        !           301:  * 
        !           302:  * NCR5380_read(register)  - read from the specified register
        !           303:  *
        !           304:  * NCR5380_write(register, value) - write to the specific register 
        !           305:  *
        !           306:  * NCR5380_implementation_fields  - additional fields needed for this 
        !           307:  *     specific implementation of the NCR5380
        !           308:  *
        !           309:  * Either real DMA *or* pseudo DMA may be implemented
        !           310:  * REAL functions : 
        !           311:  * NCR5380_REAL_DMA should be defined if real DMA is to be used.
        !           312:  * Note that the DMA setup functions should return the number of bytes 
        !           313:  *     that they were able to program the controller for.
        !           314:  *
        !           315:  * Also note that generic i386/PC versions of these macros are 
        !           316:  *     available as NCR5380_i386_dma_write_setup,
        !           317:  *     NCR5380_i386_dma_read_setup, and NCR5380_i386_dma_residual.
        !           318:  *
        !           319:  * NCR5380_dma_write_setup(instance, src, count) - initialize
        !           320:  * NCR5380_dma_read_setup(instance, dst, count) - initialize
        !           321:  * NCR5380_dma_residual(instance); - residual count
        !           322:  *
        !           323:  * PSEUDO functions :
        !           324:  * NCR5380_pwrite(instance, src, count)
        !           325:  * NCR5380_pread(instance, dst, count);
        !           326:  *
        !           327:  * If nothing specific to this implementation needs doing (ie, with external
        !           328:  * hardware), you must also define 
        !           329:  *  
        !           330:  * NCR5380_queue_command
        !           331:  * NCR5380_reset
        !           332:  * NCR5380_abort
        !           333:  * NCR5380_proc_info
        !           334:  *
        !           335:  * to be the global entry points into the specific driver, ie 
        !           336:  * #define NCR5380_queue_command t128_queue_command.
        !           337:  *
        !           338:  * If this is not done, the routines will be defined as static functions
        !           339:  * with the NCR5380* names and the user must provide a globally
        !           340:  * accessible wrapper function.
        !           341:  *
        !           342:  * The generic driver is initialized by calling NCR5380_init(instance),
        !           343:  * after setting the appropriate host specific fields and ID.  If the 
        !           344:  * driver wishes to autoprobe for an IRQ line, the NCR5380_probe_irq(instance,
        !           345:  * possible) function may be used.  Before the specific driver initialization
        !           346:  * code finishes, NCR5380_print_options should be called.
        !           347:  */
        !           348: 
        !           349: static int do_abort (struct Scsi_Host *host);
        !           350: static void do_reset (struct Scsi_Host *host);
        !           351: static struct Scsi_Host *first_instance = NULL;
        !           352: static Scsi_Host_Template *the_template = NULL;
        !           353: 
        !           354: /*
        !           355:  * Function : void initialize_SCp(Scsi_Cmnd *cmd)
        !           356:  *
        !           357:  * Purpose : initialize the saved data pointers for cmd to point to the 
        !           358:  *     start of the buffer.
        !           359:  *
        !           360:  * Inputs : cmd - Scsi_Cmnd structure to have pointers reset.
        !           361:  */
        !           362: 
        !           363: static __inline__ void initialize_SCp(Scsi_Cmnd *cmd) {
        !           364:     /* 
        !           365:      * Initialize the Scsi Pointer field so that all of the commands in the 
        !           366:      * various queues are valid.
        !           367:      */
        !           368: 
        !           369:     if (cmd->use_sg) {
        !           370:        cmd->SCp.buffer = (struct scatterlist *) cmd->buffer;
        !           371:        cmd->SCp.buffers_residual = cmd->use_sg - 1;
        !           372:        cmd->SCp.ptr = (char *) cmd->SCp.buffer->address;
        !           373:        cmd->SCp.this_residual = cmd->SCp.buffer->length;
        !           374:     } else {
        !           375:        cmd->SCp.buffer = NULL;
        !           376:        cmd->SCp.buffers_residual = 0;
        !           377:        cmd->SCp.ptr = (char *) cmd->request_buffer;
        !           378:        cmd->SCp.this_residual = cmd->request_bufflen;
        !           379:     }
        !           380: }
        !           381: 
        !           382: #include <linux/delay.h>
        !           383: 
        !           384: #ifdef NDEBUG
        !           385: static struct {
        !           386:     unsigned char mask;
        !           387:     const char * name;} 
        !           388: signals[] = {{ SR_DBP, "PARITY"}, { SR_RST, "RST" }, { SR_BSY, "BSY" }, 
        !           389:     { SR_REQ, "REQ" }, { SR_MSG, "MSG" }, { SR_CD,  "CD" }, { SR_IO, "IO" }, 
        !           390:     { SR_SEL, "SEL" }, {0, NULL}}, 
        !           391: basrs[] = {{BASR_ATN, "ATN"}, {BASR_ACK, "ACK"}, {0, NULL}},
        !           392: icrs[] = {{ICR_ASSERT_RST, "ASSERT RST"},{ICR_ASSERT_ACK, "ASSERT ACK"},
        !           393:     {ICR_ASSERT_BSY, "ASSERT BSY"}, {ICR_ASSERT_SEL, "ASSERT SEL"}, 
        !           394:     {ICR_ASSERT_ATN, "ASSERT ATN"}, {ICR_ASSERT_DATA, "ASSERT DATA"}, 
        !           395:     {0, NULL}},
        !           396: mrs[] = {{MR_BLOCK_DMA_MODE, "MODE BLOCK DMA"}, {MR_TARGET, "MODE TARGET"}, 
        !           397:     {MR_ENABLE_PAR_CHECK, "MODE PARITY CHECK"}, {MR_ENABLE_PAR_INTR, 
        !           398:     "MODE PARITY INTR"}, {MR_MONITOR_BSY, "MODE MONITOR BSY"},
        !           399:     {MR_DMA_MODE, "MODE DMA"}, {MR_ARBITRATE, "MODE ARBITRATION"}, 
        !           400:     {0, NULL}};
        !           401: 
        !           402: /*
        !           403:  * Function : void NCR5380_print(struct Scsi_Host *instance)
        !           404:  *
        !           405:  * Purpose : print the SCSI bus signals for debugging purposes
        !           406:  *
        !           407:  * Input : instance - which NCR5380
        !           408:  */
        !           409: 
        !           410: static void NCR5380_print(struct Scsi_Host *instance) {
        !           411:     NCR5380_local_declare();
        !           412:     unsigned char status, data, basr, mr, icr, i;
        !           413:     NCR5380_setup(instance);
        !           414:     cli();
        !           415:     data = NCR5380_read(CURRENT_SCSI_DATA_REG);
        !           416:     status = NCR5380_read(STATUS_REG);
        !           417:     mr = NCR5380_read(MODE_REG);
        !           418:     icr = NCR5380_read(INITIATOR_COMMAND_REG);
        !           419:     basr = NCR5380_read(BUS_AND_STATUS_REG);
        !           420:     sti();
        !           421:     printk("STATUS_REG: %02x ", status);
        !           422:     for (i = 0; signals[i].mask ; ++i) 
        !           423:        if (status & signals[i].mask)
        !           424:            printk(",%s", signals[i].name);
        !           425:     printk("\nBASR: %02x ", basr);
        !           426:     for (i = 0; basrs[i].mask ; ++i) 
        !           427:        if (basr & basrs[i].mask)
        !           428:            printk(",%s", basrs[i].name);
        !           429:     printk("\nICR: %02x ", icr);
        !           430:     for (i = 0; icrs[i].mask; ++i) 
        !           431:        if (icr & icrs[i].mask)
        !           432:            printk(",%s", icrs[i].name);
        !           433:     printk("\nMODE: %02x ", mr);
        !           434:     for (i = 0; mrs[i].mask; ++i) 
        !           435:        if (mr & mrs[i].mask)
        !           436:            printk(",%s", mrs[i].name);
        !           437:     printk("\n");
        !           438: }
        !           439: 
        !           440: static struct {
        !           441:     unsigned char value;
        !           442:     const char *name;
        !           443: } phases[] = {
        !           444: {PHASE_DATAOUT, "DATAOUT"}, {PHASE_DATAIN, "DATAIN"}, {PHASE_CMDOUT, "CMDOUT"},
        !           445: {PHASE_STATIN, "STATIN"}, {PHASE_MSGOUT, "MSGOUT"}, {PHASE_MSGIN, "MSGIN"},
        !           446: {PHASE_UNKNOWN, "UNKNOWN"}};
        !           447: 
        !           448: /* 
        !           449:  * Function : void NCR5380_print_phase(struct Scsi_Host *instance)
        !           450:  *
        !           451:  * Purpose : print the current SCSI phase for debugging purposes
        !           452:  *
        !           453:  * Input : instance - which NCR5380
        !           454:  */
        !           455: 
        !           456: static void NCR5380_print_phase(struct Scsi_Host *instance) {
        !           457:     NCR5380_local_declare();
        !           458:     unsigned char status;
        !           459:     int i;
        !           460:     NCR5380_setup(instance);
        !           461: 
        !           462:     status = NCR5380_read(STATUS_REG);
        !           463:     if (!(status & SR_REQ)) 
        !           464:        printk("scsi%d : REQ not asserted, phase unknown.\n", 
        !           465:            instance->host_no);
        !           466:     else {
        !           467:        for (i = 0; (phases[i].value != PHASE_UNKNOWN) && 
        !           468:            (phases[i].value != (status & PHASE_MASK)); ++i); 
        !           469:        printk("scsi%d : phase %s\n", instance->host_no, phases[i].name);
        !           470:     }
        !           471: }
        !           472: #endif
        !           473: 
        !           474: /*
        !           475:  * We need to have our coroutine active given these constraints : 
        !           476:  * 1.  The mutex flag, main_running, can only be set when the main 
        !           477:  *     routine can actually process data, otherwise SCSI commands
        !           478:  *     will never get issued.
        !           479:  *
        !           480:  * 2.  NCR5380_main() shouldn't be called before it has exited, because
        !           481:  *     other drivers have had kernel stack overflows in similar
        !           482:  *     situations.
        !           483:  *
        !           484:  * 3.  We don't want to inline NCR5380_main() because of space concerns,
        !           485:  *     even though it is only called in two places.
        !           486:  *
        !           487:  * So, the solution is to set the mutex in an inline wrapper for the 
        !           488:  * main coroutine, and have the main coroutine exit with interrupts 
        !           489:  * disabled after the final search through the queues so that no race 
        !           490:  * conditions are possible.
        !           491:  */
        !           492: 
        !           493: static volatile int main_running = 0;
        !           494: 
        !           495: /* 
        !           496:  * Function : run_main(void)
        !           497:  * 
        !           498:  * Purpose : insure that the coroutine is running and will process our 
        !           499:  *     request.  main_running is checked/set here (in an inline function)
        !           500:  *     rather than in NCR5380_main itself to reduce the chances of stack
        !           501:  *     overflow.
        !           502:  *
        !           503:  */
        !           504: 
        !           505: static __inline__ void run_main(void) {
        !           506:     cli();
        !           507:     if (!main_running) {
        !           508:        main_running = 1;
        !           509:        NCR5380_main();
        !           510:        /* 
        !           511:         * main_running is cleared in NCR5380_main once it can't do 
        !           512:         * more work, and NCR5380_main exits with interrupts disabled.
        !           513:         */
        !           514:        sti();
        !           515:     } else 
        !           516:        sti();
        !           517: }
        !           518: 
        !           519: #ifdef USLEEP
        !           520: #ifndef NCR5380_TIMER
        !           521: #error "NCR5380_TIMER must be defined so that this type of NCR5380 driver gets a unique timer."
        !           522: #endif
        !           523: 
        !           524: /*
        !           525:  * These need tweaking, and would probably work best as per-device 
        !           526:  * flags initialized differently for disk, tape, cd, etc devices.
        !           527:  * People with broken devices are free to experiment as to what gives
        !           528:  * the best results for them.
        !           529:  *
        !           530:  * USLEEP_SLEEP should be a minimum seek time.
        !           531:  *
        !           532:  * USLEEP_POLL should be a maximum rotational latency.
        !           533:  */
        !           534: #ifndef USLEEP_SLEEP
        !           535: /* 20 ms (reasonable hard disk speed) */
        !           536: #define USLEEP_SLEEP (20*HZ/1000)
        !           537: #endif
        !           538: /* 300 RPM (floppy speed) */
        !           539: #ifndef USLEEP_POLL
        !           540: #define USLEEP_POLL (200*HZ/1000)
        !           541: #endif
        !           542: 
        !           543: static struct Scsi_Host * expires_first = NULL;
        !           544: 
        !           545: /* 
        !           546:  * Function : int should_disconnect (unsigned char cmd)
        !           547:  *
        !           548:  * Purpose : decide weather a command would normally disconnect or 
        !           549:  *     not, since if it won't disconnect we should go to sleep.
        !           550:  *
        !           551:  * Input : cmd - opcode of SCSI command
        !           552:  *
        !           553:  * Returns : DISCONNECT_LONG if we should disconnect for a really long 
        !           554:  *     time (ie always, sleep, look for REQ active, sleep), 
        !           555:  *     DISCONNECT_TIME_TO_DATA if we would only disconnect for a normal
        !           556:  *     time-to-data delay, DISCONNECT_NONE if this command would return
        !           557:  *     immediately.
        !           558:  *
        !           559:  *      Future sleep algorithms based on time to data can exploit 
        !           560:  *      something like this so they can differentiate between "normal" 
        !           561:  *     (ie, read, write, seek) and unusual commands (ie, * format).
        !           562:  *
        !           563:  * Note : We don't deal with commands that handle an immediate disconnect,
        !           564:  *        
        !           565:  */
        !           566: 
        !           567: static int should_disconnect (unsigned char cmd) {
        !           568:     switch (cmd) {
        !           569:     case READ_6:
        !           570:     case WRITE_6:
        !           571:     case SEEK_6:
        !           572:     case READ_10:
        !           573:     case WRITE_10:
        !           574:     case SEEK_10:
        !           575:        return DISCONNECT_TIME_TO_DATA;
        !           576:     case FORMAT_UNIT:
        !           577:     case SEARCH_HIGH:
        !           578:     case SEARCH_LOW:
        !           579:     case SEARCH_EQUAL:
        !           580:        return DISCONNECT_LONG;
        !           581:     default:
        !           582:        return DISCONNECT_NONE;
        !           583:     }
        !           584: }
        !           585: 
        !           586: /*
        !           587:  * Assumes instance->time_expires has been set in higher level code.
        !           588:  */
        !           589: 
        !           590: static int NCR5380_set_timer (struct Scsi_Host *instance) {
        !           591:     struct Scsi_Host *tmp, **prev;
        !           592:     
        !           593:     cli();
        !           594:     if (((struct NCR5380_hostdata *) (instance->host_data))->next_timer) {
        !           595:        sti();
        !           596:        return -1;
        !           597:     }
        !           598: 
        !           599:     for (prev = &expires_first, tmp = expires_first; tmp; 
        !           600:        prev = &(((struct NCR5380_hostdata *) tmp->host_data)->next_timer), 
        !           601:        tmp = ((struct NCR5380_hostdata *) tmp->host_data)->next_timer)
        !           602:        if (instance->time_expires < tmp->time_expires) 
        !           603:            break;
        !           604:           
        !           605:     instance->next_timer = tmp;
        !           606:     *prev = instance;
        !           607:     timer_table[NCR5380_TIMER].expires = expires_first->time_expires;
        !           608:     timer_active |= 1 << NCR5380_TIMER;
        !           609:     sti();
        !           610:     return 0;
        !           611: }    
        !           612: 
        !           613: /* Doing something about unwanted reentrancy here might be useful */
        !           614: void NCR5380_timer_fn(void) {
        !           615:     struct Scsi_Host *instance;
        !           616:     cli();
        !           617:     for (; expires_first && expires_first->time_expires >= jiffies; ) {
        !           618:        instance = ((NCR5380_hostdata *) expires_first->host_data)->
        !           619:            expires_next;
        !           620:        ((NCR5380_hostdata *) expires_first->host_data)->expires_next = 
        !           621:            NULL;
        !           622:        ((NCR5380_hostdata *) expires_first->host_data)->time_expires = 
        !           623:            0;
        !           624:        expires_first = instance;
        !           625:     }
        !           626: 
        !           627:     if (expires_first) {
        !           628:        timer_table[NCR5380_TIMER].expires = ((NCR5380_hostdata *) 
        !           629:            expires_first->host_data)->time_expires;
        !           630:        timer_active |= (1 << NCR5380_TIMER);
        !           631:     } else {
        !           632:        timer_table[NCR5380_TIMER].expires = 0;
        !           633:        timer_active &= ~(1 << MCR5380_TIMER);
        !           634:     }
        !           635:     sti();
        !           636: 
        !           637:     run_main();
        !           638: }
        !           639: #endif /* def USLEEP */
        !           640: 
        !           641: static void NCR5380_all_init (void) {
        !           642:     static int done = 0;
        !           643:     if (!done) {
        !           644: #if (NDEBUG & NDEBUG_INIT)
        !           645:        printk("scsi : NCR5380_all_init()\n");
        !           646: #endif
        !           647:        done = 1;
        !           648: #ifdef USLEEP
        !           649:        timer_table[NCR5380_TIMER].expires = 0;
        !           650:        timer_table[NCR5380_TIMER].fn = NCR5380_timer_fn;
        !           651: #endif
        !           652:     }
        !           653: }
        !           654: 
        !           655: #ifdef AUTOPROBE_IRQ
        !           656: /*
        !           657:  * Function : int NCR5380_probe_irq (struct Scsi_Host *instance, int possible)
        !           658:  * 
        !           659:  * Purpose : autoprobe for the IRQ line used by the NCR5380.  
        !           660:  *
        !           661:  * Inputs : instance - pointer to this instance of the NCR5380 driver,
        !           662:  *          possible - bitmask of permissible interrupts.
        !           663:  *
        !           664:  * Returns : number of the IRQ selected, IRQ_NONE if no interrupt fired.
        !           665:  * 
        !           666:  * XXX no effort is made to deal with spurious interrupts. 
        !           667:  */
        !           668: 
        !           669: 
        !           670: static int probe_irq;
        !           671: static void probe_intr (int irq, void *dev_id, struct pt_regs * regs) {
        !           672:     probe_irq = irq;
        !           673: };
        !           674: 
        !           675: static int NCR5380_probe_irq (struct Scsi_Host *instance, int possible) {
        !           676:     NCR5380_local_declare();
        !           677:     struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *)
        !           678:         instance->hostdata;
        !           679:     unsigned long timeout;
        !           680:     int trying_irqs, i, mask;
        !           681:     NCR5380_setup(instance);
        !           682: 
        !           683:     for (trying_irqs = i = 0, mask = 1; i < 16; ++i, mask <<= 1) 
        !           684:        if ((mask & possible) &&  (request_irq(i, &probe_intr, SA_INTERRUPT, "NCR-probe", NULL) 
        !           685:            == 0)) 
        !           686:            trying_irqs |= mask;
        !           687: 
        !           688:     timeout = jiffies + 250*HZ/1000;
        !           689:     probe_irq = IRQ_NONE;
        !           690: 
        !           691: /*
        !           692:  * A interrupt is triggered whenever BSY = false, SEL = true
        !           693:  * and a bit set in the SELECT_ENABLE_REG is asserted on the 
        !           694:  * SCSI bus.
        !           695:  *
        !           696:  * Note that the bus is only driven when the phase control signals
        !           697:  * (I/O, C/D, and MSG) match those in the TCR, so we must reset that
        !           698:  * to zero.
        !           699:  */
        !           700: 
        !           701:     NCR5380_write(TARGET_COMMAND_REG, 0);
        !           702:     NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
        !           703:     NCR5380_write(OUTPUT_DATA_REG, hostdata->id_mask);
        !           704:     NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_DATA | 
        !           705:        ICR_ASSERT_SEL);
        !           706: 
        !           707:     while (probe_irq == IRQ_NONE && jiffies < timeout)
        !           708:        barrier();
        !           709: 
        !           710:     NCR5380_write(SELECT_ENABLE_REG, 0);
        !           711:     NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
        !           712: 
        !           713:     for (i = 0, mask = 1; i < 16; ++i, mask <<= 1)
        !           714:        if (trying_irqs & mask) 
        !           715:            free_irq(i, NULL);
        !           716: 
        !           717:     return probe_irq;
        !           718: }
        !           719: #endif /* AUTOPROBE_IRQ */
        !           720:  
        !           721: /*
        !           722:  * Function : void NCR58380_print_options (struct Scsi_Host *instance)
        !           723:  *
        !           724:  * Purpose : called by probe code indicating the NCR5380 driver
        !           725:  *          options that were selected.
        !           726:  *
        !           727:  * Inputs : instance, pointer to this instance.  Unused.
        !           728:  */
        !           729: 
        !           730: static void NCR5380_print_options (struct Scsi_Host *instance) {
        !           731:     printk(" generic options"
        !           732: #ifdef AUTOPROBE_IRQ
        !           733:     " AUTOPROBE_IRQ"
        !           734: #endif
        !           735: #ifdef AUTOSENSE 
        !           736:     " AUTOSENSE"
        !           737: #endif
        !           738: #ifdef DIFFERENTIAL
        !           739:     " DIFFERENTIAL"
        !           740: #endif
        !           741: #ifdef REAL_DMA
        !           742:     " REAL DMA"
        !           743: #endif
        !           744: #ifdef REAL_DMA_POLL
        !           745:     " REAL DMA POLL"
        !           746: #endif
        !           747: #ifdef PARITY
        !           748:     " PARITY"
        !           749: #endif
        !           750: #ifdef PSEUDO_DMA
        !           751:     " PSEUDO DMA"
        !           752: #endif
        !           753: #ifdef SCSI2
        !           754:     " SCSI-2"
        !           755: #endif
        !           756: #ifdef UNSAFE
        !           757:     " UNSAFE "
        !           758: #endif
        !           759:     );
        !           760: #ifdef USLEEP
        !           761:     printk(" USLEEP, USLEEP_POLL=%d USLEEP_SLEEP=%d", USLEEP_POLL, USLEEP_SLEEP);
        !           762: #endif
        !           763:     printk(" generic release=%d", NCR5380_PUBLIC_RELEASE);
        !           764:     if (((struct NCR5380_hostdata *)instance->hostdata)->flags & FLAG_NCR53C400) {
        !           765:        printk(" ncr53c400 release=%d", NCR53C400_PUBLIC_RELEASE);
        !           766:     }
        !           767: }
        !           768: 
        !           769: /*
        !           770:  * Function : void NCR5380_print_status (struct Scsi_Host *instance)
        !           771:  *
        !           772:  * Purpose : print commands in the various queues, called from
        !           773:  *     NCR5380_abort and NCR5380_debug to aid debugging.
        !           774:  *
        !           775:  * Inputs : instance, pointer to this instance.  
        !           776:  */
        !           777: 
        !           778: static void NCR5380_print_status (struct Scsi_Host *instance) {
        !           779:    static char pr_bfr[512];
        !           780:    char *start;
        !           781:    int len;
        !           782: 
        !           783:     printk("NCR5380 : coroutine is%s running.\n",
        !           784:        main_running ? "" : "n't");
        !           785:     
        !           786: #ifdef NDEBUG
        !           787:     NCR5380_print (instance);
        !           788:     NCR5380_print_phase (instance);
        !           789: #endif
        !           790: 
        !           791:    len = NCR5380_proc_info(pr_bfr, &start, 0, sizeof(pr_bfr),
        !           792:                        instance->host_no, 0);
        !           793:    pr_bfr[len] = 0;
        !           794:    printk("\n%s\n", pr_bfr);
        !           795:   }
        !           796: 
        !           797: /******************************************/
        !           798: /*
        !           799:  * /proc/scsi/[dtc pas16 t128 generic]/[0-ASC_NUM_BOARD_SUPPORTED]
        !           800:  *
        !           801:  * *buffer: I/O buffer
        !           802:  * **start: if inout == FALSE pointer into buffer where user read should start
        !           803:  * offset: current offset
        !           804:  * length: length of buffer
        !           805:  * hostno: Scsi_Host host_no
        !           806:  * inout: TRUE - user is writing; FALSE - user is reading
        !           807:  *
        !           808:  * Return the number of bytes read from or written
        !           809: */
        !           810: 
        !           811: #undef SPRINTF
        !           812: #define SPRINTF(args...) do { if(pos < buffer + length-80) pos += sprintf(pos, ## args); } while(0)
        !           813: static
        !           814: char *lprint_Scsi_Cmnd (Scsi_Cmnd *cmd, char *pos, char *buffer, int length);
        !           815: static
        !           816: char *lprint_command (unsigned char *cmd, char *pos, char *buffer, int len);
        !           817: static
        !           818: char *lprint_opcode(int opcode, char *pos, char *buffer, int length);
        !           819: 
        !           820: #ifndef NCR5380_proc_info
        !           821: static
        !           822: #endif
        !           823: int NCR5380_proc_info (
        !           824:      char *buffer, char **start,off_t offset,
        !           825:      int length,int hostno,int inout)
        !           826: {
        !           827:    char *pos = buffer;
        !           828:    struct Scsi_Host *instance;
        !           829:    struct NCR5380_hostdata *hostdata;
        !           830:    Scsi_Cmnd *ptr;
        !           831: 
        !           832:    for (instance = first_instance; instance &&
        !           833:         instance->host_no != hostno; instance=instance->next)
        !           834:         ;
        !           835:    if (!instance)
        !           836:       return(-ESRCH);
        !           837:    hostdata = (struct NCR5380_hostdata *)instance->hostdata;
        !           838: 
        !           839:    if (inout) { /* Has data been written to the file ? */
        !           840: #ifdef DTC_PUBLIC_RELEASE
        !           841:         dtc_wmaxi = dtc_maxi = 0;
        !           842: #endif
        !           843: #ifdef PAS16_PUBLIC_RELEASE
        !           844:         pas_wmaxi = pas_maxi = 0;
        !           845: #endif
        !           846:       return(-ENOSYS);  /* Currently this is a no-op */
        !           847:    }
        !           848:    SPRINTF("NCR5380 core release=%d.   ", NCR5380_PUBLIC_RELEASE);
        !           849:    if (((struct NCR5380_hostdata *)instance->hostdata)->flags & FLAG_NCR53C400)
        !           850:         SPRINTF("ncr53c400 release=%d.  ", NCR53C400_PUBLIC_RELEASE);
        !           851: #ifdef DTC_PUBLIC_RELEASE
        !           852:    SPRINTF("DTC 3180/3280 release %d", DTC_PUBLIC_RELEASE);
        !           853: #endif
        !           854: #ifdef T128_PUBLIC_RELEASE
        !           855:    SPRINTF("T128 release %d", T128_PUBLIC_RELEASE);
        !           856: #endif
        !           857: #ifdef GENERIC_NCR5380_PUBLIC_RELEASE
        !           858:    SPRINTF("Generic5380 release %d", GENERIC_NCR5380_PUBLIC_RELEASE);
        !           859: #endif
        !           860: #ifdef PAS16_PUBLIC_RELEASE
        !           861: SPRINTF("PAS16 release=%d", PAS16_PUBLIC_RELEASE);
        !           862: #endif
        !           863: 
        !           864:    SPRINTF("\nBase Addr: 0x%05lX    ", (long)instance->base);
        !           865:    SPRINTF("io_port: %04x      ", (int)instance->io_port);
        !           866:    if (instance->irq == IRQ_NONE)
        !           867:       SPRINTF("IRQ: None.\n");
        !           868:    else
        !           869:       SPRINTF("IRQ: %d.\n", instance->irq);
        !           870: 
        !           871: #ifdef DTC_PUBLIC_RELEASE
        !           872:    SPRINTF("Highwater I/O busy_spin_counts -- write: %d  read: %d\n",
        !           873:         dtc_wmaxi, dtc_maxi);
        !           874: #endif
        !           875: #ifdef PAS16_PUBLIC_RELEASE
        !           876:    SPRINTF("Highwater I/O busy_spin_counts -- write: %d  read: %d\n",
        !           877:         pas_wmaxi, pas_maxi);
        !           878: #endif
        !           879:     cli();
        !           880:     SPRINTF("NCR5380 : coroutine is%s running.\n", main_running ? "" : "n't");
        !           881:     if (!hostdata->connected)
        !           882:       SPRINTF("scsi%d: no currently connected command\n", instance->host_no);
        !           883:    else
        !           884:       pos = lprint_Scsi_Cmnd ((Scsi_Cmnd *) hostdata->connected,
        !           885:         pos, buffer, length);
        !           886:    SPRINTF("scsi%d: issue_queue\n", instance->host_no);
        !           887:    for (ptr = (Scsi_Cmnd *) hostdata->issue_queue; ptr;
        !           888:         ptr = (Scsi_Cmnd *) ptr->host_scribble)
        !           889:         pos = lprint_Scsi_Cmnd (ptr, pos, buffer, length);
        !           890: 
        !           891:    SPRINTF("scsi%d: disconnected_queue\n", instance->host_no);
        !           892:    for (ptr = (Scsi_Cmnd *) hostdata->disconnected_queue; ptr;
        !           893:         ptr = (Scsi_Cmnd *) ptr->host_scribble)
        !           894:         pos = lprint_Scsi_Cmnd (ptr, pos, buffer, length);
        !           895: 
        !           896:    sti();
        !           897:    *start=buffer;
        !           898:   if (pos - buffer < offset)
        !           899:     return 0;
        !           900:   else if (pos - buffer - offset < length)
        !           901:     return pos - buffer - offset;
        !           902:   return length;
        !           903: }
        !           904: 
        !           905: static 
        !           906: char *lprint_Scsi_Cmnd (Scsi_Cmnd *cmd, char *pos, char *buffer, int length) {
        !           907:    SPRINTF("scsi%d : destination target %d, lun %d\n",
        !           908:         cmd->host->host_no, cmd->target, cmd->lun);
        !           909:    SPRINTF("        command = ");
        !           910:    pos = lprint_command (cmd->cmnd, pos, buffer, length);
        !           911:    return (pos);
        !           912: }
        !           913: 
        !           914: static 
        !           915: char *lprint_command (unsigned char *command,
        !           916:      char *pos, char *buffer, int length) {
        !           917:    int i, s;
        !           918:    pos = lprint_opcode(command[0], pos, buffer, length);
        !           919:    for ( i = 1, s = COMMAND_SIZE(command[0]); i < s; ++i)
        !           920:       SPRINTF("%02x ", command[i]);
        !           921:    SPRINTF("\n");
        !           922:    return(pos);
        !           923: }
        !           924: 
        !           925: static 
        !           926: char *lprint_opcode(int opcode, char *pos, char *buffer, int length) {
        !           927:    SPRINTF("%2d (0x%02x)", opcode, opcode);
        !           928:    return(pos);
        !           929: }
        !           930: 
        !           931: 
        !           932: /* 
        !           933:  * Function : void NCR5380_init (struct Scsi_Host *instance, flags)
        !           934:  *
        !           935:  * Purpose : initializes *instance and corresponding 5380 chip,
        !           936:  *     with flags OR'd into the initial flags value.
        !           937:  *
        !           938:  * Inputs : instance - instantiation of the 5380 driver.  
        !           939:  *
        !           940:  * Notes : I assume that the host, hostno, and id bits have been
        !           941:  *     set correctly.  I don't care about the irq and other fields. 
        !           942:  * 
        !           943:  */
        !           944: 
        !           945: static void NCR5380_init (struct Scsi_Host *instance, int flags) {
        !           946:     NCR5380_local_declare();
        !           947:     int i, pass;
        !           948:     unsigned long timeout;
        !           949:     struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) 
        !           950:        instance->hostdata;
        !           951: 
        !           952:     /* 
        !           953:      * On NCR53C400 boards, NCR5380 registers are mapped 8 past 
        !           954:      * the base address.
        !           955:      */
        !           956: 
        !           957: #ifdef NCR53C400
        !           958:     if (flags & FLAG_NCR53C400)
        !           959:        instance->NCR5380_instance_name += NCR53C400_address_adjust;
        !           960: #endif
        !           961: 
        !           962:     NCR5380_setup(instance);
        !           963: 
        !           964:     NCR5380_all_init();
        !           965: 
        !           966:     hostdata->aborted = 0;
        !           967:     hostdata->id_mask = 1 << instance->this_id;
        !           968:     for (i = hostdata->id_mask; i <= 0x80; i <<= 1)
        !           969:        if (i > hostdata->id_mask)
        !           970:            hostdata->id_higher_mask |= i;
        !           971:     for (i = 0; i < 8; ++i)
        !           972:        hostdata->busy[i] = 0;
        !           973: #ifdef REAL_DMA
        !           974:     hostdata->dmalen = 0;
        !           975: #endif
        !           976:     hostdata->targets_present = 0;
        !           977:     hostdata->connected = NULL;
        !           978:     hostdata->issue_queue = NULL;
        !           979:     hostdata->disconnected_queue = NULL;
        !           980: #ifdef NCR5380_STATS
        !           981:     for (i = 0; i < 8; ++i) {
        !           982:        hostdata->time_read[i] = 0;
        !           983:        hostdata->time_write[i] = 0;
        !           984:        hostdata->bytes_read[i] = 0;
        !           985:        hostdata->bytes_write[i] = 0;
        !           986:     }
        !           987:     hostdata->timebase = 0;
        !           988:     hostdata->pendingw = 0;
        !           989:     hostdata->pendingr = 0;
        !           990: #endif
        !           991: 
        !           992:     /* The CHECK code seems to break the 53C400. Will check it later maybe */
        !           993:     if (flags & FLAG_NCR53C400)
        !           994:        hostdata->flags = FLAG_HAS_LAST_BYTE_SENT | flags;
        !           995:     else
        !           996:        hostdata->flags = FLAG_CHECK_LAST_BYTE_SENT | flags;
        !           997: 
        !           998:     if (!the_template) {
        !           999:        the_template = instance->hostt;
        !          1000:        first_instance = instance;
        !          1001:     }
        !          1002:        
        !          1003: 
        !          1004: #ifdef USLEEP
        !          1005:     hostdata->time_expires = 0;
        !          1006:     hostdata->next_timer = NULL;
        !          1007: #endif
        !          1008: 
        !          1009: #ifndef AUTOSENSE
        !          1010:     if ((instance->cmd_per_lun > 1) || instance->can_queue > 1)) 
        !          1011:         printk("scsi%d : WARNING : support for multiple outstanding commands enabled\n"
        !          1012:                "         without AUTOSENSE option, contingent allegiance conditions may\n"
        !          1013:                "         be incorrectly cleared.\n", instance->host_no);
        !          1014: #endif /* def AUTOSENSE */
        !          1015: 
        !          1016:     NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
        !          1017:     NCR5380_write(MODE_REG, MR_BASE);
        !          1018:     NCR5380_write(TARGET_COMMAND_REG, 0);
        !          1019:     NCR5380_write(SELECT_ENABLE_REG, 0);
        !          1020: 
        !          1021: #ifdef NCR53C400
        !          1022:     if (hostdata->flags & FLAG_NCR53C400) {
        !          1023:        NCR5380_write(C400_CONTROL_STATUS_REG, CSR_BASE);
        !          1024:     }
        !          1025: #endif
        !          1026: 
        !          1027:     /* 
        !          1028:      * Detect and correct bus wedge problems.
        !          1029:      *
        !          1030:      * If the system crashed, it may have crashed in a state 
        !          1031:      * where a SCSI command was still executing, and the 
        !          1032:      * SCSI bus is not in a BUS FREE STATE.
        !          1033:      *
        !          1034:      * If this is the case, we'll try to abort the currently
        !          1035:      * established nexus which we know nothing about, and that
        !          1036:      * failing, do a hard reset of the SCSI bus 
        !          1037:      */
        !          1038: 
        !          1039:     for (pass = 1; (NCR5380_read(STATUS_REG) & SR_BSY) &&
        !          1040:          pass <= 6 ; ++pass) {
        !          1041:        switch (pass) {
        !          1042:        case 1:
        !          1043:        case 3:
        !          1044:        case 5:
        !          1045:            printk("scsi%d: SCSI bus busy, waiting up to five seconds\n",
        !          1046:                instance->host_no);
        !          1047:            timeout = jiffies + 5*HZ;
        !          1048:            while (jiffies < timeout && (NCR5380_read(STATUS_REG) & SR_BSY));
        !          1049:            break;
        !          1050:        case 2:
        !          1051:            printk("scsi%d: bus busy, attempting abort\n",
        !          1052:                instance->host_no);
        !          1053:            do_abort (instance);
        !          1054:            break;
        !          1055:        case 4:
        !          1056:            printk("scsi%d: bus busy, attempting reset\n",
        !          1057:                instance->host_no);
        !          1058:            do_reset (instance);
        !          1059:            break;
        !          1060:        case 6:
        !          1061:            printk("scsi%d: bus locked solid or invalid override\n",
        !          1062:                instance->host_no);
        !          1063:        }
        !          1064:     }
        !          1065: }
        !          1066: 
        !          1067: /* 
        !          1068:  * Function : int NCR5380_queue_command (Scsi_Cmnd *cmd, 
        !          1069:  *     void (*done)(Scsi_Cmnd *)) 
        !          1070:  *
        !          1071:  * Purpose :  enqueues a SCSI command
        !          1072:  *
        !          1073:  * Inputs : cmd - SCSI command, done - function called on completion, with
        !          1074:  *     a pointer to the command descriptor.
        !          1075:  * 
        !          1076:  * Returns : 0
        !          1077:  *
        !          1078:  * Side effects : 
        !          1079:  *      cmd is added to the per instance issue_queue, with minor 
        !          1080:  *     twiddling done to the host specific fields of cmd.  If the 
        !          1081:  *     main coroutine is not running, it is restarted.
        !          1082:  *
        !          1083:  */
        !          1084: 
        !          1085: /* Only make static if a wrapper function is used */
        !          1086: #ifndef NCR5380_queue_command
        !          1087: static
        !          1088: #endif
        !          1089: int NCR5380_queue_command (Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *)) {
        !          1090:     struct Scsi_Host *instance = cmd->host;
        !          1091:     struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *)
        !          1092:        instance->hostdata;
        !          1093:     Scsi_Cmnd *tmp;
        !          1094: 
        !          1095: #if (NDEBUG & NDEBUG_NO_WRITE)
        !          1096:     switch (cmd->cmnd[0]) {
        !          1097:     case WRITE_6:
        !          1098:     case WRITE_10:
        !          1099:        printk("scsi%d : WRITE attempted with NO_WRITE debugging flag set\n",
        !          1100:            instance->host_no);
        !          1101:        cmd->result = (DID_ERROR << 16);
        !          1102:        done(cmd);
        !          1103:        return 0;
        !          1104:     }
        !          1105: #endif /* (NDEBUG & NDEBUG_NO_WRITE) */
        !          1106: 
        !          1107: #ifdef NCR5380_STATS
        !          1108: # if 0
        !          1109:     if (!hostdata->connected && !hostdata->issue_queue &&
        !          1110:        !hostdata->disconnected_queue) {
        !          1111:        hostdata->timebase = jiffies;
        !          1112:     }
        !          1113: # endif
        !          1114: # ifdef NCR5380_STAT_LIMIT
        !          1115:     if (cmd->request_bufflen > NCR5380_STAT_LIMIT)
        !          1116: # endif
        !          1117:        switch (cmd->cmnd[0])
        !          1118:        {
        !          1119:            case WRITE:
        !          1120:            case WRITE_6:
        !          1121:            case WRITE_10:
        !          1122:                hostdata->time_write[cmd->target] -= (jiffies - hostdata->timebase);
        !          1123:                hostdata->bytes_write[cmd->target] += cmd->request_bufflen;
        !          1124:                hostdata->pendingw++;
        !          1125:                break;
        !          1126:            case READ:
        !          1127:            case READ_6:
        !          1128:            case READ_10:
        !          1129:                hostdata->time_read[cmd->target] -= (jiffies - hostdata->timebase);
        !          1130:                hostdata->bytes_read[cmd->target] += cmd->request_bufflen;
        !          1131:                hostdata->pendingr++;
        !          1132:                break;
        !          1133:        }
        !          1134: #endif
        !          1135: 
        !          1136:     /* 
        !          1137:      * We use the host_scribble field as a pointer to the next command  
        !          1138:      * in a queue 
        !          1139:      */
        !          1140: 
        !          1141:     cmd->host_scribble = NULL;
        !          1142:     cmd->scsi_done = done;
        !          1143: 
        !          1144:     cmd->result = 0;
        !          1145: 
        !          1146: 
        !          1147:     /* 
        !          1148:      * Insert the cmd into the issue queue. Note that REQUEST SENSE 
        !          1149:      * commands are added to the head of the queue since any command will
        !          1150:      * clear the contingent allegiance condition that exists and the 
        !          1151:      * sense data is only guaranteed to be valid while the condition exists.
        !          1152:      */
        !          1153: 
        !          1154:     cli();
        !          1155:     if (!(hostdata->issue_queue) || (cmd->cmnd[0] == REQUEST_SENSE)) {
        !          1156:        LIST(cmd, hostdata->issue_queue);
        !          1157:        cmd->host_scribble = (unsigned char *) hostdata->issue_queue;
        !          1158:        hostdata->issue_queue = cmd;
        !          1159:     } else {
        !          1160:        for (tmp = (Scsi_Cmnd *) hostdata->issue_queue; tmp->host_scribble; 
        !          1161:                tmp = (Scsi_Cmnd *) tmp->host_scribble);
        !          1162:        LIST(cmd, tmp);
        !          1163:        tmp->host_scribble = (unsigned char *) cmd;
        !          1164:     }
        !          1165: #if (NDEBUG & NDEBUG_QUEUES)
        !          1166:     printk("scsi%d : command added to %s of queue\n", instance->host_no,
        !          1167:        (cmd->cmnd[0] == REQUEST_SENSE) ? "head" : "tail");
        !          1168: #endif
        !          1169: 
        !          1170: /* Run the coroutine if it isn't already running. */
        !          1171:     run_main();
        !          1172:     return 0;
        !          1173: }
        !          1174: 
        !          1175: /*
        !          1176:  * Function : NCR5380_main (void) 
        !          1177:  *
        !          1178:  * Purpose : NCR5380_main is a coroutine that runs as long as more work can 
        !          1179:  *     be done on the NCR5380 host adapters in a system.  Both 
        !          1180:  *     NCR5380_queue_command() and NCR5380_intr() will try to start it 
        !          1181:  *     in case it is not running.
        !          1182:  * 
        !          1183:  * NOTE : NCR5380_main exits with interrupts *disabled*, the caller should 
        !          1184:  *  reenable them.  This prevents reentrancy and kernel stack overflow.
        !          1185:  */    
        !          1186:     
        !          1187: static void NCR5380_main (void) {
        !          1188:     Scsi_Cmnd *tmp, *prev;
        !          1189:     struct Scsi_Host *instance;
        !          1190:     struct NCR5380_hostdata *hostdata;
        !          1191:     int done;
        !          1192: 
        !          1193:     /*
        !          1194:      * We run (with interrupts disabled) until we're sure that none of 
        !          1195:      * the host adapters have anything that can be done, at which point 
        !          1196:      * we set main_running to 0 and exit.
        !          1197:      *
        !          1198:      * Interrupts are enabled before doing various other internal 
        !          1199:      * instructions, after we've decided that we need to run through
        !          1200:      * the loop again.
        !          1201:      *
        !          1202:      * this should prevent any race conditions.
        !          1203:      */
        !          1204: 
        !          1205:     do {
        !          1206:        cli(); /* Freeze request queues */
        !          1207:        done = 1;
        !          1208:        for (instance = first_instance; instance && 
        !          1209:            instance->hostt == the_template; instance=instance->next) {
        !          1210:            hostdata = (struct NCR5380_hostdata *) instance->hostdata;
        !          1211:            cli();
        !          1212:            if (!hostdata->connected) {
        !          1213: #if (NDEBUG & NDEBUG_MAIN)
        !          1214:                printk("scsi%d : not connected\n", instance->host_no);
        !          1215: #endif
        !          1216:                /*
        !          1217:                 * Search through the issue_queue for a command destined
        !          1218:                 * for a target that's not busy.
        !          1219:                 */
        !          1220: #if (NDEBUG & NDEBUG_LISTS)
        !          1221:                for (tmp= (Scsi_Cmnd *) hostdata->issue_queue, prev=NULL; tmp && (tmp != prev); prev=tmp, tmp=(Scsi_Cmnd*)tmp->host_scribble)
        !          1222:                    ;
        !          1223:                    /*printk("%p  ", tmp);*/
        !          1224:                if ((tmp == prev) && tmp) printk(" LOOP\n");/* else printk("\n");*/
        !          1225: #endif
        !          1226:                for (tmp = (Scsi_Cmnd *) hostdata->issue_queue, 
        !          1227:                    prev = NULL; tmp; prev = tmp, tmp = (Scsi_Cmnd *) 
        !          1228:                    tmp->host_scribble) {
        !          1229: 
        !          1230: #if (NDEBUG & NDEBUG_LISTS)
        !          1231:                    if (prev != tmp)
        !          1232:                        printk("MAIN tmp=%p   target=%d   busy=%d lun=%d\n", tmp, tmp->target, hostdata->busy[tmp->target], tmp->lun);
        !          1233: #endif
        !          1234:                    /*  When we find one, remove it from the issue queue. */
        !          1235:                    if (!(hostdata->busy[tmp->target] & (1 << tmp->lun))) {
        !          1236:                        if (prev) {
        !          1237:                            REMOVE(prev,prev->host_scribble,tmp,tmp->host_scribble);
        !          1238:                            prev->host_scribble = tmp->host_scribble;
        !          1239:                        } else {
        !          1240:                            REMOVE(-1,hostdata->issue_queue,tmp,tmp->host_scribble);
        !          1241:                            hostdata->issue_queue = (Scsi_Cmnd *) tmp->host_scribble;
        !          1242:                        }
        !          1243:                        tmp->host_scribble = NULL;
        !          1244: 
        !          1245:                        /* reenable interrupts after finding one */
        !          1246:                        sti();
        !          1247: 
        !          1248:                        /* 
        !          1249:                         * Attempt to establish an I_T_L nexus here. 
        !          1250:                         * On success, instance->hostdata->connected is set.
        !          1251:                         * On failure, we must add the command back to the
        !          1252:                         *   issue queue so we can keep trying. 
        !          1253:                         */
        !          1254: #if (NDEBUG & (NDEBUG_MAIN | NDEBUG_QUEUES))
        !          1255:                        printk("scsi%d : main() : command for target %d lun %d removed from issue_queue\n",
        !          1256:                            instance->host_no, tmp->target, tmp->lun);
        !          1257: #endif
        !          1258:                
        !          1259:                        /*
        !          1260:                         * A successful selection is defined as one that 
        !          1261:                         * leaves us with the command connected and 
        !          1262:                         * in hostdata->connected, OR has terminated the
        !          1263:                         * command.
        !          1264:                         *
        !          1265:                         * With successful commands, we fall through
        !          1266:                         * and see if we can do an information transfer,
        !          1267:                         * with failures we will restart.
        !          1268:                         */
        !          1269: 
        !          1270:                        if (!NCR5380_select(instance, tmp, 
        !          1271:                        /* 
        !          1272:                         * REQUEST SENSE commands are issued without tagged
        !          1273:                         * queueing, even on SCSI-II devices because the 
        !          1274:                         * contingent allegiance condition exists for the 
        !          1275:                         * entire unit.
        !          1276:                         */
        !          1277:                            (tmp->cmnd[0] == REQUEST_SENSE) ? TAG_NONE : 
        !          1278:                            TAG_NEXT)) {
        !          1279:                            break;
        !          1280:                        } else {
        !          1281:                            cli();
        !          1282:                            LIST(tmp, hostdata->issue_queue);
        !          1283:                            tmp->host_scribble = (unsigned char *) 
        !          1284:                                hostdata->issue_queue;
        !          1285:                            hostdata->issue_queue = tmp;
        !          1286:                            done = 0;
        !          1287:                            sti();
        !          1288: #if (NDEBUG & (NDEBUG_MAIN | NDEBUG_QUEUES))
        !          1289:                        printk("scsi%d : main(): select() failed, returned to issue_queue\n",
        !          1290:                            instance->host_no);
        !          1291: #endif
        !          1292:                        }
        !          1293:                    } /* if target/lun is not busy */
        !          1294:                } /* for */
        !          1295:            } /* if (!hostdata->connected) */
        !          1296:                
        !          1297:            if (hostdata->connected 
        !          1298: #ifdef REAL_DMA
        !          1299:                && !hostdata->dmalen
        !          1300: #endif
        !          1301: #ifdef USLEEP
        !          1302:                && (!hostdata->time_expires || hostdata->time_expires >= jiffies)
        !          1303: #endif
        !          1304:                ) {
        !          1305:                sti();
        !          1306: #if (NDEBUG & NDEBUG_MAIN)
        !          1307:                printk("scsi%d : main() : performing information transfer\n",
        !          1308:                        instance->host_no);
        !          1309: #endif
        !          1310:                NCR5380_information_transfer(instance);
        !          1311: #if (NDEBUG & NDEBUG_MAIN)
        !          1312:                printk("scsi%d : main() : done set false\n", instance->host_no);
        !          1313: #endif
        !          1314:                done = 0;
        !          1315:            } else 
        !          1316:                break;
        !          1317:        } /* for instance */
        !          1318:     } while (!done);
        !          1319:     main_running = 0;
        !          1320: }
        !          1321: 
        !          1322: #ifndef DONT_USE_INTR
        !          1323: /*
        !          1324:  * Function : void NCR5380_intr (int irq)
        !          1325:  * 
        !          1326:  * Purpose : handle interrupts, reestablishing I_T_L or I_T_L_Q nexuses
        !          1327:  *     from the disconnected queue, and restarting NCR5380_main() 
        !          1328:  *     as required.
        !          1329:  *
        !          1330:  * Inputs : int irq, irq that caused this interrupt.
        !          1331:  *
        !          1332:  */
        !          1333: 
        !          1334: static void NCR5380_intr (int irq, void *dev_id, struct pt_regs * regs) {
        !          1335:     NCR5380_local_declare(); 
        !          1336:     struct Scsi_Host *instance;
        !          1337:     int done;
        !          1338:     unsigned char basr;
        !          1339: #if (NDEBUG & NDEBUG_INTR)
        !          1340:     printk("scsi : NCR5380 irq %d triggered\n", irq);
        !          1341: #endif
        !          1342:     do {
        !          1343:        done = 1;
        !          1344:        for (instance = first_instance; instance && (instance->hostt == 
        !          1345:            the_template); instance = instance->next)
        !          1346:            if (instance->irq == irq) {
        !          1347:                
        !          1348:                /* Look for pending interrupts */
        !          1349:                NCR5380_setup(instance);
        !          1350:                basr = NCR5380_read(BUS_AND_STATUS_REG);
        !          1351:                /* XXX dispatch to appropriate routine if found and done=0 */
        !          1352:                if (basr & BASR_IRQ) {
        !          1353: #if (NDEBUG & NDEBUG_INTR)
        !          1354:                    NCR5380_print(instance);
        !          1355: #endif
        !          1356:                    if ((NCR5380_read(STATUS_REG) & (SR_SEL | SR_IO)) == 
        !          1357:                        (SR_SEL | SR_IO)) {
        !          1358:                        done = 0;
        !          1359:                        sti();
        !          1360: #if (NDEBUG & NDEBUG_INTR)
        !          1361:                        printk("scsi%d : SEL interrupt\n", instance->host_no);
        !          1362: #endif
        !          1363:                        NCR5380_reselect(instance);
        !          1364:                        (void) NCR5380_read(RESET_PARITY_INTERRUPT_REG);
        !          1365:                    } else if (basr & BASR_PARITY_ERROR) {
        !          1366: #if (NDEBUG & NDEBUG_INTR)
        !          1367:                        printk("scsi%d : PARITY interrupt\n", instance->host_no);
        !          1368: #endif
        !          1369:                        (void) NCR5380_read(RESET_PARITY_INTERRUPT_REG);
        !          1370:                    } else if ((NCR5380_read(STATUS_REG) & SR_RST) == SR_RST) {
        !          1371: #if (NDEBUG & NDEBUG_INTR)
        !          1372:                        printk("scsi%d : RESET interrupt\n", instance->host_no);
        !          1373: #endif
        !          1374:                        (void)NCR5380_read(RESET_PARITY_INTERRUPT_REG);
        !          1375:                    } else {
        !          1376: /*  
        !          1377:  * XXX the rest of the interrupt conditions should *only* occur during a 
        !          1378:  * DMA transfer, which I haven't gotten around to fixing yet.
        !          1379:  */
        !          1380: 
        !          1381: #if defined(REAL_DMA)
        !          1382:                    /*
        !          1383:                     * We should only get PHASE MISMATCH and EOP interrupts
        !          1384:                     * if we have DMA enabled, so do a sanity check based on
        !          1385:                     * the current setting of the MODE register.
        !          1386:                     */
        !          1387: 
        !          1388:                        if ((NCR5380_read(MODE_REG) & MR_DMA) && ((basr & 
        !          1389:                            BASR_END_DMA_TRANSFER) || 
        !          1390:                            !(basr & BASR_PHASE_MATCH))) {
        !          1391:                            int transfered;
        !          1392: 
        !          1393:                            if (!hostdata->connected) 
        !          1394:                                panic("scsi%d : received end of DMA interrupt with no connected cmd\n",
        !          1395:                                    instance->hostno);
        !          1396: 
        !          1397:                            transfered = (hostdata->dmalen - NCR5380_dma_residual(instance));
        !          1398:                            hostdata->connected->SCp.this_residual -= transferred;
        !          1399:                            hostdata->connected->SCp.ptr += transferred;
        !          1400:                            hostdata->dmalen = 0;
        !          1401: 
        !          1402:                            (void) NCR5380_read(RESET_PARITY_INTERRUPT_REG);
        !          1403: #if NCR_TIMEOUT
        !          1404:                            {
        !          1405:                              unsigned long timeout = jiffies + NCR_TIMEOUT;
        !          1406: 
        !          1407:                              while (NCR5380_read(BUS_AND_STATUS_REG) & BASR_ACK
        !          1408:                                     && jiffies < timeout)
        !          1409:                                ;
        !          1410:                              if (jiffies >= timeout)
        !          1411:                                printk("scsi%d: timeout at NCR5380.c:%d\n", 
        !          1412:                                    host->host_no, __LINE__);
        !          1413:                            }
        !          1414: #else /* NCR_TIMEOUT */
        !          1415:                            while (NCR5380_read(BUS_AND_STATUS_REG) & BASR_ACK);
        !          1416: #endif
        !          1417: 
        !          1418:                            NCR5380_write(MODE_REG, MR_BASE);
        !          1419:                            NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
        !          1420:                        }
        !          1421: #else
        !          1422: #if (NDEBUG & NDEBUG_INTR)
        !          1423:                    printk("scsi : unknown interrupt, BASR 0x%X, MR 0x%X, SR 0x%x\n", basr, NCR5380_read(MODE_REG), NCR5380_read(STATUS_REG));
        !          1424: #endif
        !          1425:                    (void) NCR5380_read(RESET_PARITY_INTERRUPT_REG);
        !          1426: #endif
        !          1427:                    } 
        !          1428:                } /* if BASR_IRQ */
        !          1429:                if (!done) 
        !          1430:                    run_main();
        !          1431:            } /* if (instance->irq == irq) */
        !          1432:     } while (!done);
        !          1433: }
        !          1434: #endif
        !          1435: 
        !          1436: #ifdef NCR5380_STATS
        !          1437: static void collect_stats(struct NCR5380_hostdata* hostdata, Scsi_Cmnd* cmd)
        !          1438: {
        !          1439: # ifdef NCR5380_STAT_LIMIT
        !          1440:     if (cmd->request_bufflen > NCR5380_STAT_LIMIT)
        !          1441: # endif
        !          1442:        switch (cmd->cmnd[0])
        !          1443:        {
        !          1444:            case WRITE:
        !          1445:            case WRITE_6:
        !          1446:            case WRITE_10:
        !          1447:                hostdata->time_write[cmd->target] += (jiffies - hostdata->timebase);
        !          1448:                /*hostdata->bytes_write[cmd->target] += cmd->request_bufflen;*/
        !          1449:                hostdata->pendingw--;
        !          1450:                break;
        !          1451:            case READ:
        !          1452:            case READ_6:
        !          1453:            case READ_10:
        !          1454:                hostdata->time_read[cmd->target] += (jiffies - hostdata->timebase);
        !          1455:                /*hostdata->bytes_read[cmd->target] += cmd->request_bufflen;*/
        !          1456:                hostdata->pendingr--;
        !          1457:                break;
        !          1458:        }
        !          1459: }
        !          1460: #endif
        !          1461: 
        !          1462: /* 
        !          1463:  * Function : int NCR5380_select (struct Scsi_Host *instance, Scsi_Cmnd *cmd, 
        !          1464:  *     int tag);
        !          1465:  *
        !          1466:  * Purpose : establishes I_T_L or I_T_L_Q nexus for new or existing command,
        !          1467:  *     including ARBITRATION, SELECTION, and initial message out for 
        !          1468:  *     IDENTIFY and queue messages. 
        !          1469:  *
        !          1470:  * Inputs : instance - instantiation of the 5380 driver on which this 
        !          1471:  *     target lives, cmd - SCSI command to execute, tag - set to TAG_NEXT for 
        !          1472:  *     new tag, TAG_NONE for untagged queueing, otherwise set to the tag for 
        !          1473:  *     the command that is presently connected.
        !          1474:  * 
        !          1475:  * Returns : -1 if selection could not execute for some reason,
        !          1476:  *     0 if selection succeeded or failed because the target 
        !          1477:  *     did not respond.
        !          1478:  *
        !          1479:  * Side effects : 
        !          1480:  *     If bus busy, arbitration failed, etc, NCR5380_select() will exit 
        !          1481:  *             with registers as they should have been on entry - ie
        !          1482:  *             SELECT_ENABLE will be set appropriately, the NCR5380
        !          1483:  *             will cease to drive any SCSI bus signals.
        !          1484:  *
        !          1485:  *     If successful : I_T_L or I_T_L_Q nexus will be established, 
        !          1486:  *             instance->connected will be set to cmd.  
        !          1487:  *             SELECT interrupt will be disabled.
        !          1488:  *
        !          1489:  *     If failed (no target) : cmd->scsi_done() will be called, and the 
        !          1490:  *             cmd->result host byte set to DID_BAD_TARGET.
        !          1491:  */
        !          1492: 
        !          1493: static int NCR5380_select (struct Scsi_Host *instance, Scsi_Cmnd *cmd,
        !          1494:     int tag) {
        !          1495:     NCR5380_local_declare();
        !          1496:     struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata*) 
        !          1497:        instance->hostdata;
        !          1498:     unsigned char tmp[3], phase;
        !          1499:     unsigned char *data;
        !          1500:     int len;
        !          1501:     unsigned long timeout;
        !          1502:     NCR5380_setup(instance);
        !          1503: 
        !          1504:     hostdata->restart_select = 0;
        !          1505: #if defined (NDEBUG) && (NDEBUG & NDEBUG_ARBITRATION) 
        !          1506:     NCR5380_print(instance);
        !          1507:     printk("scsi%d : starting arbitration, id = %d\n", instance->host_no,
        !          1508:        instance->this_id);
        !          1509: #endif
        !          1510:     cli(); 
        !          1511: 
        !          1512:     /* 
        !          1513:      * Set the phase bits to 0, otherwise the NCR5380 won't drive the 
        !          1514:      * data bus during SELECTION.
        !          1515:      */
        !          1516: 
        !          1517:     NCR5380_write(TARGET_COMMAND_REG, 0);
        !          1518: 
        !          1519: 
        !          1520:     /* 
        !          1521:      * Start arbitration.
        !          1522:      */
        !          1523:     
        !          1524:     NCR5380_write(OUTPUT_DATA_REG, hostdata->id_mask);
        !          1525:     NCR5380_write(MODE_REG, MR_ARBITRATE);
        !          1526: 
        !          1527:     sti();
        !          1528: 
        !          1529:     /* Wait for arbitration logic to complete */
        !          1530: #if NCR_TIMEOUT
        !          1531:     {
        !          1532:       unsigned long timeout = jiffies + 2*NCR_TIMEOUT;
        !          1533: 
        !          1534:       while (!(NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_PROGRESS)
        !          1535:           && jiffies < timeout)
        !          1536:        ;
        !          1537:       if (jiffies >= timeout)
        !          1538:       {
        !          1539:        printk("scsi: arbitration timeout at %d\n", __LINE__);
        !          1540:        NCR5380_write(MODE_REG, MR_BASE);
        !          1541:        NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
        !          1542:        return -1;
        !          1543:       }
        !          1544:     }
        !          1545: #else /* NCR_TIMEOUT */
        !          1546:     while (!(NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_PROGRESS));
        !          1547: #endif
        !          1548: 
        !          1549: #if (NDEBUG & NDEBUG_ARBITRATION) 
        !          1550:     printk("scsi%d : arbitration complete\n", instance->host_no);
        !          1551: /* Avoid GCC 2.4.5 asm needs to many reloads error */
        !          1552:     __asm__("nop");
        !          1553: #endif
        !          1554: 
        !          1555:     /* 
        !          1556:      * The arbitration delay is 2.2us, but this is a minimum and there is 
        !          1557:      * no maximum so we can safely sleep for ceil(2.2) usecs to accommodate
        !          1558:      * the integral nature of udelay().
        !          1559:      *
        !          1560:      */
        !          1561: 
        !          1562:     udelay(3);
        !          1563: 
        !          1564:     /* Check for lost arbitration */
        !          1565:     if ((NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST) ||
        !          1566:        (NCR5380_read(CURRENT_SCSI_DATA_REG) & hostdata->id_higher_mask) ||
        !          1567:        (NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST)) {
        !          1568:        NCR5380_write(MODE_REG, MR_BASE); 
        !          1569: #if (NDEBUG & NDEBUG_ARBITRATION)
        !          1570:     printk("scsi%d : lost arbitration, deasserting MR_ARBITRATE\n", 
        !          1571:        instance->host_no);
        !          1572: #endif
        !          1573:        return -1;
        !          1574:     }
        !          1575: 
        !          1576: 
        !          1577: 
        !          1578:     NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_SEL);
        !          1579:     
        !          1580:     if (NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST) {
        !          1581:        NCR5380_write(MODE_REG, MR_BASE);
        !          1582:        NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
        !          1583: #if (NDEBUG & NDEBUG_ARBITRATION)
        !          1584:     printk("scsi%d : lost arbitration, deasserting ICR_ASSERT_SEL\n", 
        !          1585:        instance->host_no);
        !          1586: #endif
        !          1587:        return -1;
        !          1588:     }
        !          1589: 
        !          1590:     /* 
        !          1591:      * Again, bus clear + bus settle time is 1.2us, however, this is 
        !          1592:      * a minimum so we'll udelay ceil(1.2)
        !          1593:      */
        !          1594: 
        !          1595:     udelay(2)        !          1596: 
        !          1597: #if (NDEBUG & NDEBUG_ARBITRATION)
        !          1598:     printk("scsi%d : won arbitration\n", instance->host_no);
        !          1599: #endif
        !          1600: 
        !          1601: 
        !          1602:     /* 
        !          1603:      * Now that we have won arbitration, start Selection process, asserting 
        !          1604:      * the host and target ID's on the SCSI bus.
        !          1605:      */
        !          1606: 
        !          1607:     NCR5380_write(OUTPUT_DATA_REG, (hostdata->id_mask | (1 << cmd->target)));
        !          1608: 
        !          1609:     /* 
        !          1610:      * Raise ATN while SEL is true before BSY goes false from arbitration,
        !          1611:      * since this is the only way to guarantee that we'll get a MESSAGE OUT
        !          1612:      * phase immediately after selection.
        !          1613:      */
        !          1614: 
        !          1615:     NCR5380_write(INITIATOR_COMMAND_REG, (ICR_BASE | ICR_ASSERT_BSY | 
        !          1616:        ICR_ASSERT_DATA | ICR_ASSERT_ATN | ICR_ASSERT_SEL ));
        !          1617:     NCR5380_write(MODE_REG, MR_BASE);
        !          1618: 
        !          1619:     /* 
        !          1620:      * Reselect interrupts must be turned off prior to the dropping of BSY,
        !          1621:      * otherwise we will trigger an interrupt.
        !          1622:      */
        !          1623:     NCR5380_write(SELECT_ENABLE_REG, 0);
        !          1624: 
        !          1625:     /*
        !          1626:      * The initiator shall then wait at least two deskew delays and release 
        !          1627:      * the BSY signal.
        !          1628:      */
        !          1629:     udelay(1);        /* wingel -- wait two bus deskew delay >2*45ns */
        !          1630: 
        !          1631:     /* Reset BSY */
        !          1632:     NCR5380_write(INITIATOR_COMMAND_REG, (ICR_BASE | ICR_ASSERT_DATA | 
        !          1633:        ICR_ASSERT_ATN | ICR_ASSERT_SEL));
        !          1634: 
        !          1635:     /* 
        !          1636:      * Something weird happens when we cease to drive BSY - looks
        !          1637:      * like the board/chip is letting us do another read before the 
        !          1638:      * appropriate propagation delay has expired, and we're confusing
        !          1639:      * a BSY signal from ourselves as the target's response to SELECTION.
        !          1640:      *
        !          1641:      * A small delay (the 'C++' frontend breaks the pipeline with an
        !          1642:      * unnecessary jump, making it work on my 386-33/Trantor T128, the
        !          1643:      * tighter 'C' code breaks and requires this) solves the problem - 
        !          1644:      * the 1 us delay is arbitrary, and only used because this delay will 
        !          1645:      * be the same on other platforms and since it works here, it should 
        !          1646:      * work there.
        !          1647:      *
        !          1648:      * wingel suggests that this could be due to failing to wait
        !          1649:      * one deskew delay.
        !          1650:      */
        !          1651: 
        !          1652:     udelay(1);
        !          1653: 
        !          1654: #if (NDEBUG & NDEBUG_SELECTION)
        !          1655:     printk("scsi%d : selecting target %d\n", instance->host_no, cmd->target);
        !          1656: #endif
        !          1657: 
        !          1658:     /* 
        !          1659:      * The SCSI specification calls for a 250 ms timeout for the actual 
        !          1660:      * selection.
        !          1661:      */
        !          1662: 
        !          1663:     timeout = jiffies + 250*HZ/1000;
        !          1664: 
        !          1665:     /* 
        !          1666:      * XXX very interesting - we're seeing a bounce where the BSY we 
        !          1667:      * asserted is being reflected / still asserted (propagation delay?)
        !          1668:      * and it's detecting as true.  Sigh.
        !          1669:      */
        !          1670: 
        !          1671:     while ((jiffies < timeout) && !(NCR5380_read(STATUS_REG) & 
        !          1672:        (SR_BSY | SR_IO)));
        !          1673: 
        !          1674:     if ((NCR5380_read(STATUS_REG) & (SR_SEL | SR_IO)) == 
        !          1675:            (SR_SEL | SR_IO)) {
        !          1676:            NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
        !          1677:            NCR5380_reselect(instance);
        !          1678:            printk ("scsi%d : reselection after won arbitration?\n",
        !          1679:                instance->host_no);
        !          1680:            NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
        !          1681:            return -1;
        !          1682:     }
        !          1683: 
        !          1684:     /* 
        !          1685:      * No less than two deskew delays after the initiator detects the 
        !          1686:      * BSY signal is true, it shall release the SEL signal and may 
        !          1687:      * change the DATA BUS.                                     -wingel
        !          1688:      */
        !          1689: 
        !          1690:     udelay(1);
        !          1691: 
        !          1692:     NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);
        !          1693: 
        !          1694:     if (!(NCR5380_read(STATUS_REG) & SR_BSY)) {
        !          1695:        NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
        !          1696:        if (hostdata->targets_present & (1 << cmd->target)) {
        !          1697:            printk("scsi%d : weirdness\n", instance->host_no);
        !          1698:            if (hostdata->restart_select)
        !          1699:                printk("\trestart select\n");
        !          1700: #ifdef NDEBUG
        !          1701:            NCR5380_print (instance);
        !          1702: #endif
        !          1703:            NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
        !          1704:            return -1;
        !          1705:        }
        !          1706:        cmd->result = DID_BAD_TARGET << 16;
        !          1707: #ifdef NCR5380_STATS
        !          1708:        collect_stats(hostdata, cmd);
        !          1709: #endif
        !          1710:        cmd->scsi_done(cmd);
        !          1711:        NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
        !          1712: #if (NDEBUG & NDEBUG_SELECTION)
        !          1713:        printk("scsi%d : target did not respond within 250ms\n", 
        !          1714:            instance->host_no);
        !          1715: #endif
        !          1716:        NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
        !          1717:        return 0;
        !          1718:     } 
        !          1719: 
        !          1720:     hostdata->targets_present |= (1 << cmd->target);
        !          1721: 
        !          1722:     /*
        !          1723:      * Since we followed the SCSI spec, and raised ATN while SEL 
        !          1724:      * was true but before BSY was false during selection, the information
        !          1725:      * transfer phase should be a MESSAGE OUT phase so that we can send the
        !          1726:      * IDENTIFY message.
        !          1727:      * 
        !          1728:      * If SCSI-II tagged queuing is enabled, we also send a SIMPLE_QUEUE_TAG
        !          1729:      * message (2 bytes) with a tag ID that we increment with every command
        !          1730:      * until it wraps back to 0.
        !          1731:      *
        !          1732:      * XXX - it turns out that there are some broken SCSI-II devices,
        !          1733:      *      which claim to support tagged queuing but fail when more than
        !          1734:      *      some number of commands are issued at once.
        !          1735:      */
        !          1736: 
        !          1737:     /* Wait for start of REQ/ACK handshake */
        !          1738: #ifdef NCR_TIMEOUT
        !          1739:     {
        !          1740:       unsigned long timeout = jiffies + NCR_TIMEOUT;
        !          1741:  
        !          1742:       while (!(NCR5380_read(STATUS_REG) & SR_REQ) && jiffies < timeout);
        !          1743: 
        !          1744:       if (jiffies >= timeout) {
        !          1745:         printk("scsi%d: timeout at NCR5380.c:%d\n", __LINE__);
        !          1746:         NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
        !          1747:         return -1;
        !          1748:       }
        !          1749:     }
        !          1750: #else /* NCR_TIMEOUT */
        !          1751:     while (!(NCR5380_read(STATUS_REG) & SR_REQ));
        !          1752: #endif /* def NCR_TIMEOUT */
        !          1753: 
        !          1754: #if (NDEBUG & NDEBUG_SELECTION)
        !          1755:     printk("scsi%d : target %d selected, going into MESSAGE OUT phase.\n",
        !          1756:        instance->host_no, cmd->target);
        !          1757: #endif
        !          1758:     tmp[0] = IDENTIFY(((instance->irq == IRQ_NONE) ? 0 : 1), cmd->lun);
        !          1759: #ifdef SCSI2
        !          1760:     if (cmd->device->tagged_queue && (tag != TAG_NONE)) {
        !          1761:        tmp[1] = SIMPLE_QUEUE_TAG;
        !          1762:        if (tag == TAG_NEXT) {
        !          1763:            /* 0 is TAG_NONE, used to imply no tag for this command */
        !          1764:            if (cmd->device->current_tag == 0)
        !          1765:                cmd->device->current_tag = 1;
        !          1766: 
        !          1767:            cmd->tag = cmd->device->current_tag;
        !          1768:            cmd->device->current_tag++;
        !          1769:        } else  
        !          1770:            cmd->tag = (unsigned char) tag;
        !          1771: 
        !          1772:        tmp[2] = cmd->tag;
        !          1773:        hostdata->last_message = SIMPLE_QUEUE_TAG;
        !          1774:        len = 3;
        !          1775:     } else 
        !          1776: #endif /* def SCSI2 */
        !          1777:     {
        !          1778:        len = 1;
        !          1779:        cmd->tag=0;
        !          1780:     }
        !          1781: 
        !          1782:     /* Send message(s) */
        !          1783:     data = tmp;
        !          1784:     phase = PHASE_MSGOUT;
        !          1785:     NCR5380_transfer_pio(instance, &phase, &len, &data);
        !          1786: #if (NDEBUG & NDEBUG_SELECTION)
        !          1787:     printk("scsi%d : nexus established.\n", instance->host_no);
        !          1788: #endif
        !          1789:     /* XXX need to handle errors here */
        !          1790:     hostdata->connected = cmd;
        !          1791: #ifdef SCSI2
        !          1792:     if (!cmd->device->tagged_queue)
        !          1793: #endif    
        !          1794:        hostdata->busy[cmd->target] |= (1 << cmd->lun);
        !          1795: 
        !          1796:     initialize_SCp(cmd);
        !          1797: 
        !          1798: 
        !          1799:     return 0;
        !          1800: }
        !          1801: 
        !          1802: /* 
        !          1803:  * Function : int NCR5380_transfer_pio (struct Scsi_Host *instance, 
        !          1804:  *      unsigned char *phase, int *count, unsigned char **data)
        !          1805:  *
        !          1806:  * Purpose : transfers data in given phase using polled I/O
        !          1807:  *
        !          1808:  * Inputs : instance - instance of driver, *phase - pointer to 
        !          1809:  *     what phase is expected, *count - pointer to number of 
        !          1810:  *     bytes to transfer, **data - pointer to data pointer.
        !          1811:  * 
        !          1812:  * Returns : -1 when different phase is entered without transferring
        !          1813:  *     maximum number of bytes, 0 if all bytes or transfered or exit
        !          1814:  *     is in same phase.
        !          1815:  *
        !          1816:  *     Also, *phase, *count, *data are modified in place.
        !          1817:  *
        !          1818:  * XXX Note : handling for bus free may be useful.
        !          1819:  */
        !          1820: 
        !          1821: /*
        !          1822:  * Note : this code is not as quick as it could be, however it 
        !          1823:  * IS 100% reliable, and for the actual data transfer where speed
        !          1824:  * counts, we will always do a pseudo DMA or DMA transfer.
        !          1825:  */
        !          1826: 
        !          1827: static int NCR5380_transfer_pio (struct Scsi_Host *instance, 
        !          1828:        unsigned char *phase, int *count, unsigned char **data) {
        !          1829:     NCR5380_local_declare();
        !          1830:     register unsigned char p = *phase, tmp;
        !          1831:     register int c = *count;
        !          1832:     register unsigned char *d = *data;
        !          1833:     NCR5380_setup(instance);
        !          1834: 
        !          1835: #if (NDEBUG & NDEBUG_PIO)
        !          1836:     if (!(p & SR_IO))
        !          1837:       printk("scsi%d : pio write %d bytes\n", instance->host_no, c);
        !          1838:     else
        !          1839:       printk("scsi%d : pio read %d bytes\n", instance->host_no, c);
        !          1840: #endif
        !          1841: 
        !          1842:     /* 
        !          1843:      * The NCR5380 chip will only drive the SCSI bus when the 
        !          1844:      * phase specified in the appropriate bits of the TARGET COMMAND
        !          1845:      * REGISTER match the STATUS REGISTER
        !          1846:      */
        !          1847: 
        !          1848:     NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(p));
        !          1849: 
        !          1850:     do {
        !          1851:        /* 
        !          1852:         * Wait for assertion of REQ, after which the phase bits will be 
        !          1853:         * valid 
        !          1854:         */
        !          1855:        while (!((tmp = NCR5380_read(STATUS_REG)) & SR_REQ));
        !          1856: 
        !          1857: #if (NDEBUG & NDEBUG_HANDSHAKE)
        !          1858:        printk("scsi%d : REQ detected\n", instance->host_no);
        !          1859: #endif
        !          1860: 
        !          1861:        /* Check for phase mismatch */  
        !          1862:        if ((tmp & PHASE_MASK) != p) {
        !          1863: #if (NDEBUG & NDEBUG_PIO)
        !          1864:            printk("scsi%d : phase mismatch\n", instance->host_no);
        !          1865:            NCR5380_print_phase(instance);
        !          1866: #endif
        !          1867:            break;
        !          1868:        }
        !          1869: 
        !          1870:        /* Do actual transfer from SCSI bus to / from memory */
        !          1871:        if (!(p & SR_IO)) 
        !          1872:            NCR5380_write(OUTPUT_DATA_REG, *d);
        !          1873:        else 
        !          1874:            *d = NCR5380_read(CURRENT_SCSI_DATA_REG);
        !          1875: 
        !          1876:        ++d;
        !          1877: 
        !          1878:        /* 
        !          1879:         * The SCSI standard suggests that in MSGOUT phase, the initiator
        !          1880:         * should drop ATN on the last byte of the message phase
        !          1881:         * after REQ has been asserted for the handshake but before
        !          1882:         * the initiator raises ACK.
        !          1883:         */
        !          1884: 
        !          1885:        if (!(p & SR_IO)) {
        !          1886:            if (!((p & SR_MSG) && c > 1)) {
        !          1887:                NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | 
        !          1888:                    ICR_ASSERT_DATA);
        !          1889: #if (NDEBUG & NDEBUG_PIO)
        !          1890:        NCR5380_print(instance);
        !          1891: #endif
        !          1892:                NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | 
        !          1893:                        ICR_ASSERT_DATA | ICR_ASSERT_ACK);
        !          1894:            } else {
        !          1895:                NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE |
        !          1896:                    ICR_ASSERT_DATA | ICR_ASSERT_ATN);
        !          1897: #if (NDEBUG & NDEBUG_PIO)
        !          1898:        NCR5380_print(instance);
        !          1899: #endif
        !          1900:                NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | 
        !          1901:                    ICR_ASSERT_DATA | ICR_ASSERT_ATN | ICR_ASSERT_ACK);
        !          1902:            }
        !          1903:        } else {
        !          1904: #if (NDEBUG & NDEBUG_PIO)
        !          1905:        NCR5380_print(instance);
        !          1906: #endif
        !          1907:        NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ACK);
        !          1908:        }
        !          1909: 
        !          1910:        while (NCR5380_read(STATUS_REG) & SR_REQ);
        !          1911: 
        !          1912: #if (NDEBUG & NDEBUG_HANDSHAKE)
        !          1913:            printk("scsi%d : req false, handshake complete\n", instance->host_no);
        !          1914: #endif
        !          1915: 
        !          1916: /*
        !          1917:  * We have several special cases to consider during REQ/ACK handshaking : 
        !          1918:  * 1.  We were in MSGOUT phase, and we are on the last byte of the 
        !          1919:  *     message.  ATN must be dropped as ACK is dropped.
        !          1920:  *
        !          1921:  * 2.  We are in a MSGIN phase, and we are on the last byte of the  
        !          1922:  *     message.  We must exit with ACK asserted, so that the calling
        !          1923:  *     code may raise ATN before dropping ACK to reject the message.
        !          1924:  *
        !          1925:  * 3.  ACK and ATN are clear and the target may proceed as normal.
        !          1926:  */
        !          1927:        if (!(p == PHASE_MSGIN && c == 1)) {  
        !          1928:            if (p == PHASE_MSGOUT && c > 1)
        !          1929:                NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);
        !          1930:            else
        !          1931:                NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
        !          1932:        } 
        !          1933:     } while (--c);
        !          1934: 
        !          1935: #if (NDEBUG & NDEBUG_PIO) 
        !          1936:     printk("scsi%d : residual %d\n", instance->host_no, c);
        !          1937: #endif
        !          1938: 
        !          1939:     *count = c;
        !          1940:     *data = d;
        !          1941:     tmp = NCR5380_read(STATUS_REG);
        !          1942:     if (tmp & SR_REQ)
        !          1943:        *phase = tmp & PHASE_MASK;
        !          1944:     else 
        !          1945:        *phase = PHASE_UNKNOWN;
        !          1946: 
        !          1947:     if (!c || (*phase == p))
        !          1948:        return 0;
        !          1949:     else 
        !          1950:        return -1;
        !          1951: }
        !          1952: 
        !          1953: static void do_reset (struct Scsi_Host *host) {
        !          1954:     NCR5380_local_declare();
        !          1955:     NCR5380_setup(host);
        !          1956: 
        !          1957:     cli();
        !          1958:     NCR5380_write(TARGET_COMMAND_REG, 
        !          1959:        PHASE_SR_TO_TCR(NCR5380_read(STATUS_REG) & PHASE_MASK));
        !          1960:     NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_RST);
        !          1961:     udelay(25);
        !          1962:     NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
        !          1963:     sti();
        !          1964: }
        !          1965: 
        !          1966: /*
        !          1967:  * Function : do_abort (Scsi_Host *host)
        !          1968:  * 
        !          1969:  * Purpose : abort the currently established nexus.  Should only be 
        !          1970:  *     called from a routine which can drop into a 
        !          1971:  * 
        !          1972:  * Returns : 0 on success, -1 on failure.
        !          1973:  */
        !          1974: 
        !          1975: static int do_abort (struct Scsi_Host *host) {
        !          1976:     NCR5380_local_declare();
        !          1977:     unsigned char tmp, *msgptr, phase;
        !          1978:     int len;
        !          1979:     NCR5380_setup(host);
        !          1980: 
        !          1981: 
        !          1982:     /* Request message out phase */
        !          1983:     NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);
        !          1984: 
        !          1985:     /* 
        !          1986:      * Wait for the target to indicate a valid phase by asserting 
        !          1987:      * REQ.  Once this happens, we'll have either a MSGOUT phase 
        !          1988:      * and can immediately send the ABORT message, or we'll have some 
        !          1989:      * other phase and will have to source/sink data.
        !          1990:      * 
        !          1991:      * We really don't care what value was on the bus or what value
        !          1992:      * the target sees, so we just handshake.
        !          1993:      */
        !          1994:     
        !          1995:     while (!(tmp = NCR5380_read(STATUS_REG)) & SR_REQ);
        !          1996: 
        !          1997:     NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(tmp));
        !          1998: 
        !          1999:     if ((tmp & PHASE_MASK) != PHASE_MSGOUT) {
        !          2000:        NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN | 
        !          2001:            ICR_ASSERT_ACK);
        !          2002:        while (NCR5380_read(STATUS_REG) & SR_REQ);
        !          2003:        NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);
        !          2004:     }
        !          2005:    
        !          2006:     tmp = ABORT;
        !          2007:     msgptr = &tmp;
        !          2008:     len = 1;
        !          2009:     phase = PHASE_MSGOUT;
        !          2010:     NCR5380_transfer_pio (host, &phase, &len, &msgptr);
        !          2011: 
        !          2012:     /*
        !          2013:      * If we got here, and the command completed successfully,
        !          2014:      * we're about to go into bus free state.
        !          2015:      */
        !          2016: 
        !          2017:     return len ? -1 : 0;
        !          2018: }
        !          2019: 
        !          2020: #if defined(REAL_DMA) || defined(PSEUDO_DMA) || defined (REAL_DMA_POLL)
        !          2021: /* 
        !          2022:  * Function : int NCR5380_transfer_dma (struct Scsi_Host *instance, 
        !          2023:  *      unsigned char *phase, int *count, unsigned char **data)
        !          2024:  *
        !          2025:  * Purpose : transfers data in given phase using either real
        !          2026:  *     or pseudo DMA.
        !          2027:  *
        !          2028:  * Inputs : instance - instance of driver, *phase - pointer to 
        !          2029:  *     what phase is expected, *count - pointer to number of 
        !          2030:  *     bytes to transfer, **data - pointer to data pointer.
        !          2031:  * 
        !          2032:  * Returns : -1 when different phase is entered without transferring
        !          2033:  *     maximum number of bytes, 0 if all bytes or transfered or exit
        !          2034:  *     is in same phase.
        !          2035:  *
        !          2036:  *     Also, *phase, *count, *data are modified in place.
        !          2037:  *
        !          2038:  */
        !          2039: 
        !          2040: 
        !          2041: static int NCR5380_transfer_dma (struct Scsi_Host *instance, 
        !          2042:     unsigned char *phase, int *count, unsigned char **data) {
        !          2043:     NCR5380_local_declare();
        !          2044:     register int c = *count;
        !          2045:     register unsigned char p = *phase;
        !          2046:     register unsigned char *d = *data;
        !          2047:     unsigned char tmp;
        !          2048:     int foo;
        !          2049: #if defined(REAL_DMA_POLL)
        !          2050:     int cnt, toPIO;
        !          2051:     unsigned char saved_data = 0, overrun = 0, residue;
        !          2052: #endif
        !          2053: 
        !          2054:     struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) 
        !          2055:        instance->hostdata;
        !          2056: 
        !          2057:     NCR5380_setup(instance);
        !          2058: 
        !          2059:     if ((tmp = (NCR5380_read(STATUS_REG) & PHASE_MASK)) != p) {
        !          2060:        *phase = tmp;
        !          2061:        return -1;
        !          2062:     }
        !          2063: #if defined(REAL_DMA) || defined(REAL_DMA_POLL) 
        !          2064: #ifdef READ_OVERRUNS
        !          2065:      if (p & SR_IO) {
        !          2066:        c -= 2;
        !          2067:      }
        !          2068: #endif
        !          2069: #if (NDEBUG & NDEBUG_DMA)
        !          2070:     printk("scsi%d : initializing DMA channel %d for %s, %d bytes %s %0x\n",
        !          2071:        instance->host_no, instance->dma_channel, (p & SR_IO) ? "reading" :
        !          2072:        "writing", c, (p & SR_IO) ? "to" : "from", (unsigned) d);
        !          2073: #endif
        !          2074:     hostdata->dma_len = (p & SR_IO) ?
        !          2075:        NCR5380_dma_read_setup(instance, d, c) : 
        !          2076:        NCR5380_dma_write_setup(instance, d, c);
        !          2077: #endif
        !          2078: 
        !          2079:     NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(p));
        !          2080: 
        !          2081: #ifdef REAL_DMA
        !          2082:     NCR5380_write(MODE_REG, MR_BASE | MR_DMA_MODE | MR_ENABLE_EOP_INTR | MR_MONITOR_BSY);
        !          2083: #elif defined(REAL_DMA_POLL)
        !          2084:     NCR5380_write(MODE_REG, MR_BASE | MR_DMA_MODE);
        !          2085: #else
        !          2086:     /*
        !          2087:      * Note : on my sample board, watch-dog timeouts occurred when interrupts
        !          2088:      * were not disabled for the duration of a single DMA transfer, from 
        !          2089:      * before the setting of DMA mode to after transfer of the last byte.
        !          2090:      */
        !          2091: 
        !          2092: #if defined(PSEUDO_DMA) && !defined(UNSAFE)
        !          2093:     cli();
        !          2094: #endif
        !          2095:     /* KLL May need eop and parity in 53c400 */
        !          2096:     if (hostdata->flags & FLAG_NCR53C400)
        !          2097:        NCR5380_write(MODE_REG, MR_BASE | MR_DMA_MODE | MR_ENABLE_PAR_CHECK
        !          2098:        | MR_ENABLE_PAR_INTR | MR_ENABLE_EOP_INTR | MR_DMA_MODE
        !          2099:        | MR_MONITOR_BSY);
        !          2100:     else
        !          2101:        NCR5380_write(MODE_REG, MR_BASE | MR_DMA_MODE);
        !          2102: #endif /* def REAL_DMA */
        !          2103: 
        !          2104: #if (NDEBUG & NDEBUG_DMA) & 0
        !          2105:     printk("scsi%d : mode reg = 0x%X\n", instance->host_no, NCR5380_read(MODE_REG));
        !          2106: #endif
        !          2107: 
        !          2108: /* 
        !          2109:  * FOO stuff. For some UNAPPARENT reason, I'm getting 
        !          2110:  * watchdog timers fired on bootup for NO APPARENT REASON, meaning it's
        !          2111:  * probably a timing problem.
        !          2112:  *
        !          2113:  * Since this is the only place I have back-to-back writes, perhaps this 
        !          2114:  * is the problem?
        !          2115:  */
        !          2116: 
        !          2117:     if (p & SR_IO) {
        !          2118: #ifndef FOO
        !          2119:        udelay(1);
        !          2120: #endif
        !          2121:        NCR5380_write(START_DMA_INITIATOR_RECEIVE_REG, 0);
        !          2122:     } else {
        !          2123: #ifndef FOO
        !          2124:        udelay(1);
        !          2125: #endif
        !          2126:        NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_DATA);
        !          2127: #ifndef FOO
        !          2128:        udelay(1);
        !          2129: #endif
        !          2130:        NCR5380_write(START_DMA_SEND_REG, 0);
        !          2131: #ifndef FOO
        !          2132:        udelay(1);
        !          2133: #endif
        !          2134:     }
        !          2135: 
        !          2136: #if defined(REAL_DMA_POLL)
        !          2137:     do {
        !          2138:        tmp = NCR5380_read(BUS_AND_STATUS_REG);
        !          2139:     } while ((tmp & BASR_PHASE_MATCH) && !(tmp & (BASR_BUSY_ERROR | 
        !          2140:        BASR_END_DMA_TRANSFER)));
        !          2141: 
        !          2142: /*
        !          2143:   At this point, either we've completed DMA, or we have a phase mismatch,
        !          2144:   or we've unexpectedly lost BUSY (which is a real error).
        !          2145: 
        !          2146:   For write DMAs, we want to wait until the last byte has been
        !          2147:   transferred out over the bus before we turn off DMA mode.  Alas, there
        !          2148:   seems to be no terribly good way of doing this on a 5380 under all
        !          2149:   conditions.  For non-scatter-gather operations, we can wait until REQ
        !          2150:   and ACK both go false, or until a phase mismatch occurs.  Gather-writes
        !          2151:   are nastier, since the device will be expecting more data than we
        !          2152:   are prepared to send it, and REQ will remain asserted.  On a 53C8[01] we
        !          2153:   could test LAST BIT SENT to assure transfer (I imagine this is precisely
        !          2154:   why this signal was added to the newer chips) but on the older 538[01]
        !          2155:   this signal does not exist.  The workaround for this lack is a watchdog;
        !          2156:   we bail out of the wait-loop after a modest amount of wait-time if
        !          2157:   the usual exit conditions are not met.  Not a terribly clean or
        !          2158:   correct solution :-%
        !          2159: 
        !          2160:   Reads are equally tricky due to a nasty characteristic of the NCR5380.
        !          2161:   If the chip is in DMA mode for an READ, it will respond to a target's
        !          2162:   REQ by latching the SCSI data into the INPUT DATA register and asserting
        !          2163:   ACK, even if it has _already_ been notified by the DMA controller that
        !          2164:   the current DMA transfer has completed!  If the NCR5380 is then taken
        !          2165:   out of DMA mode, this already-acknowledged byte is lost.
        !          2166: 
        !          2167:   This is not a problem for "one DMA transfer per command" reads, because
        !          2168:   the situation will never arise... either all of the data is DMA'ed
        !          2169:   properly, or the target switches to MESSAGE IN phase to signal a
        !          2170:   disconnection (either operation bringing the DMA to a clean halt).
        !          2171:   However, in order to handle scatter-reads, we must work around the
        !          2172:   problem.  The chosen fix is to DMA N-2 bytes, then check for the
        !          2173:   condition before taking the NCR5380 out of DMA mode.  One or two extra
        !          2174:   bytes are transferred via PIO as necessary to fill out the original
        !          2175:   request.
        !          2176: */
        !          2177: 
        !          2178:     if (p & SR_IO) {
        !          2179: #ifdef READ_OVERRUNS
        !          2180:       udelay(10);
        !          2181:       if (((NCR5380_read(BUS_AND_STATUS_REG) & (BASR_PHASE_MATCH|BASR_ACK)) ==
        !          2182:           (BASR_PHASE_MATCH | BASR_ACK))) {
        !          2183:        saved_data = NCR5380_read(INPUT_DATA_REGISTER);
        !          2184:        overrun = 1;
        !          2185:       }
        !          2186: #endif
        !          2187:     } else {
        !          2188:       int limit = 100;
        !          2189:       while (((tmp = NCR5380_read(BUS_AND_STATUS_REG)) & BASR_ACK) ||
        !          2190:            (NCR5380_read(STATUS_REG) & SR_REQ)) {
        !          2191:        if (!(tmp & BASR_PHASE_MATCH)) break;
        !          2192:        if (--limit < 0) break;
        !          2193:       }
        !          2194:     }
        !          2195: 
        !          2196: 
        !          2197: #if (NDEBUG & NDEBUG_DMA)
        !          2198:     printk("scsi%d : polled DMA transfer complete, basr 0x%X, sr 0x%X\n",
        !          2199:           instance->host_no, tmp, NCR5380_read(STATUS_REG));
        !          2200: #endif
        !          2201: 
        !          2202:     NCR5380_write(MODE_REG, MR_BASE);
        !          2203:     NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
        !          2204: 
        !          2205:     residue = NCR5380_dma_residual(instance);
        !          2206:     c -= residue;
        !          2207:     *count -= c;
        !          2208:     *data += c;
        !          2209:     *phase = NCR5380_read(STATUS_REG) & PHASE_MASK;
        !          2210: 
        !          2211: #ifdef READ_OVERRUNS
        !          2212:     if (*phase == p && (p & SR_IO) && residue == 0) {
        !          2213:       if (overrun) {
        !          2214: #if (NDEBUG & NDEBUG_DMA)
        !          2215:        printk("Got an input overrun, using saved byte\n");
        !          2216: #endif
        !          2217:        **data = saved_data;
        !          2218:        *data += 1;
        !          2219:        *count -= 1;
        !          2220:        cnt = toPIO = 1;
        !          2221:       } else {
        !          2222:        printk("No overrun??\n");
        !          2223:        cnt = toPIO = 2;
        !          2224:       }
        !          2225: #if (NDEBUG & NDEBUG_DMA)
        !          2226:       printk("Doing %d-byte PIO to 0x%X\n", cnt, *data);
        !          2227: #endif
        !          2228:       NCR5380_transfer_pio(instance, phase, &cnt, data);
        !          2229:       *count -= toPIO - cnt;
        !          2230:     }
        !          2231: #endif        
        !          2232: 
        !          2233: #if (NDEBUG & NDEBUG_DMA)
        !          2234:      printk("Return with data ptr = 0x%X, count %d, last 0x%X, next 0x%X\n",
        !          2235:            *data, *count, *(*data+*count-1), *(*data+*count));
        !          2236: #endif
        !          2237:      return 0;
        !          2238:      
        !          2239: #elif defined(REAL_DMA)
        !          2240:     return 0;
        !          2241: #else /* defined(REAL_DMA_POLL) */
        !          2242:     if (p & SR_IO) {
        !          2243: #ifdef DMA_WORKS_RIGHT
        !          2244:         foo = NCR5380_pread(instance, d, c);
        !          2245: #else
        !          2246:        int diff = 1;
        !          2247:        if (hostdata->flags & FLAG_NCR53C400) {
        !          2248:            diff=0;
        !          2249:        }
        !          2250: 
        !          2251:        if (!(foo = NCR5380_pread(instance, d, c - diff))) {
        !          2252:            /*
        !          2253:             * We can't disable DMA mode after successfully transferring 
        !          2254:             * what we plan to be the last byte, since that would open up
        !          2255:             * a race condition where if the target asserted REQ before 
        !          2256:             * we got the DMA mode reset, the NCR5380 would have latched
        !          2257:             * an additional byte into the INPUT DATA register and we'd
        !          2258:             * have dropped it.
        !          2259:             * 
        !          2260:             * The workaround was to transfer one fewer bytes than we 
        !          2261:             * intended to with the pseudo-DMA read function, wait for 
        !          2262:             * the chip to latch the last byte, read it, and then disable
        !          2263:             * pseudo-DMA mode.
        !          2264:             * 
        !          2265:             * After REQ is asserted, the NCR5380 asserts DRQ and ACK.
        !          2266:             * REQ is deasserted when ACK is asserted, and not reasserted
        !          2267:             * until ACK goes false.  Since the NCR5380 won't lower ACK
        !          2268:             * until DACK is asserted, which won't happen unless we twiddle
        !          2269:             * the DMA port or we take the NCR5380 out of DMA mode, we 
        !          2270:             * can guarantee that we won't handshake another extra 
        !          2271:             * byte.
        !          2272:             */
        !          2273: 
        !          2274:            if (!(hostdata->flags & FLAG_NCR53C400)) {
        !          2275:                while (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_DRQ));
        !          2276:                /* Wait for clean handshake */
        !          2277:                while (NCR5380_read(STATUS_REG) & SR_REQ);
        !          2278:                d[c - 1] = NCR5380_read(INPUT_DATA_REG);
        !          2279:            }
        !          2280:        }
        !          2281: #endif
        !          2282:     } else {
        !          2283: #ifdef DMA_WORKS_RIGHT
        !          2284:         foo = NCR5380_pwrite(instance, d, c);
        !          2285: #else
        !          2286:         int timeout;
        !          2287: #if (NDEBUG & NDEBUG_C400_PWRITE)
        !          2288:        printk("About to pwrite %d bytes\n", c);
        !          2289: #endif
        !          2290:        if (!(foo = NCR5380_pwrite(instance, d, c))) {
        !          2291:            /*
        !          2292:             * Wait for the last byte to be sent.  If REQ is being asserted for 
        !          2293:             * the byte we're interested, we'll ACK it and it will go false.  
        !          2294:             */
        !          2295:            if (!(hostdata->flags & FLAG_HAS_LAST_BYTE_SENT)) {
        !          2296:                timeout = 20000;
        !          2297: #if 1
        !          2298: #if 1
        !          2299:                while (!(NCR5380_read(BUS_AND_STATUS_REG) & 
        !          2300:                        BASR_DRQ) && (NCR5380_read(BUS_AND_STATUS_REG) &
        !          2301:                        BASR_PHASE_MATCH));
        !          2302: #else
        !          2303:                if (NCR5380_read(STATUS_REG) & SR_REQ) {
        !          2304:                    for (; timeout && 
        !          2305:                        !(NCR5380_read(BUS_AND_STATUS_REG) & BASR_ACK); 
        !          2306:                        --timeout);
        !          2307:                    for (; timeout && (NCR5380_read(STATUS_REG) & SR_REQ);
        !          2308:                        --timeout);
        !          2309:                } 
        !          2310: #endif
        !          2311:        
        !          2312: 
        !          2313: #if (NDEBUG & NDEBUG_LAST_BYTE_SENT)
        !          2314:                if (!timeout) 
        !          2315:                    printk("scsi%d : timed out on last byte\n",
        !          2316:                            instance->host_no);
        !          2317: #endif
        !          2318: 
        !          2319: 
        !          2320:                if (hostdata->flags & FLAG_CHECK_LAST_BYTE_SENT) {
        !          2321:                    hostdata->flags &= ~FLAG_CHECK_LAST_BYTE_SENT;
        !          2322:                    if (NCR5380_read(TARGET_COMMAND_REG) & TCR_LAST_BYTE_SENT) {
        !          2323:                        hostdata->flags |= FLAG_HAS_LAST_BYTE_SENT;
        !          2324: #if (NDEBUG & NDEBUG_LAST_BYTE_SENT)
        !          2325:                        printk("scsi%d : last bit sent works\n", 
        !          2326:                            instance->host_no);
        !          2327: #endif
        !          2328:                    }
        !          2329:                }
        !          2330:            } else  {
        !          2331: #if (NDEBUG & NDEBUG_C400_PWRITE)
        !          2332:                printk("Waiting for LASTBYTE\n");
        !          2333: #endif
        !          2334:                while (!(NCR5380_read(TARGET_COMMAND_REG) & TCR_LAST_BYTE_SENT));
        !          2335: #if (NDEBUG & NDEBUG_C400_PWRITE)
        !          2336:                printk("Got LASTBYTE\n");
        !          2337: #endif
        !          2338:            }
        !          2339: #else
        !          2340:            udelay (5);
        !          2341: #endif
        !          2342:        }
        !          2343: #endif
        !          2344:     }
        !          2345: 
        !          2346:     NCR5380_write(MODE_REG, MR_BASE);
        !          2347:     NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
        !          2348: 
        !          2349:     if ((!(p & SR_IO)) && (hostdata->flags & FLAG_NCR53C400)) {
        !          2350: #if (NDEBUG & NDEBUG_C400_PWRITE)
        !          2351:        printk("53C400w: Checking for IRQ\n");
        !          2352: #endif
        !          2353:        if (NCR5380_read(BUS_AND_STATUS_REG) & BASR_IRQ) {
        !          2354: #if (NDEBUG & NDEBUG_C400_PWRITE)
        !          2355:            printk("53C400w:    got it, reading reset interrupt reg\n");
        !          2356: #endif
        !          2357:            NCR5380_read(RESET_PARITY_INTERRUPT_REG);
        !          2358:        } else {
        !          2359:            printk("53C400w:    IRQ NOT THERE!\n");
        !          2360:        }
        !          2361:     }
        !          2362: 
        !          2363:     *data = d + c;
        !          2364:     *count = 0;
        !          2365:     *phase = NCR5380_read(STATUS_REG) & PHASE_MASK;
        !          2366: #if 0
        !          2367:     NCR5380_print_phase(instance);
        !          2368: #endif
        !          2369: #if defined(PSEUDO_DMA) && !defined(UNSAFE)
        !          2370:     sti();
        !          2371: #endif /* defined(REAL_DMA_POLL) */
        !          2372:     return foo;
        !          2373: #endif /* def REAL_DMA */
        !          2374: }
        !          2375: #endif /* defined(REAL_DMA) | defined(PSEUDO_DMA) */
        !          2376: 
        !          2377: /*
        !          2378:  * Function : NCR5380_information_transfer (struct Scsi_Host *instance)
        !          2379:  *
        !          2380:  * Purpose : run through the various SCSI phases and do as the target 
        !          2381:  *     directs us to.  Operates on the currently connected command, 
        !          2382:  *     instance->connected.
        !          2383:  *
        !          2384:  * Inputs : instance, instance for which we are doing commands
        !          2385:  *
        !          2386:  * Side effects : SCSI things happen, the disconnected queue will be 
        !          2387:  *     modified if a command disconnects, *instance->connected will
        !          2388:  *     change.
        !          2389:  *
        !          2390:  * XXX Note : we need to watch for bus free or a reset condition here 
        !          2391:  *     to recover from an unexpected bus free condition.
        !          2392:  */
        !          2393:  
        !          2394: static void NCR5380_information_transfer (struct Scsi_Host *instance) {
        !          2395:     NCR5380_local_declare();
        !          2396:     struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) 
        !          2397:        instance->hostdata;
        !          2398:     unsigned char msgout = NOP;
        !          2399:     int sink = 0;
        !          2400:     int len;
        !          2401: #if defined(PSEUDO_DMA) || defined(REAL_DMA_POLL)
        !          2402:     int transfersize;
        !          2403: #endif
        !          2404:     unsigned char *data;
        !          2405:     unsigned char phase, tmp, extended_msg[10], old_phase=0xff;
        !          2406:     Scsi_Cmnd *cmd = (Scsi_Cmnd *) hostdata->connected;
        !          2407:     NCR5380_setup(instance);
        !          2408: 
        !          2409:     while (1) {
        !          2410:        tmp = NCR5380_read(STATUS_REG);
        !          2411:        /* We only have a valid SCSI phase when REQ is asserted */
        !          2412:        if (tmp & SR_REQ) {
        !          2413:            phase = (tmp & PHASE_MASK); 
        !          2414:            if (phase != old_phase) {
        !          2415:                old_phase = phase;
        !          2416: #if (NDEBUG & NDEBUG_INFORMATION)
        !          2417:                NCR5380_print_phase(instance);
        !          2418: #endif
        !          2419:            }
        !          2420:            
        !          2421:            if (sink && (phase != PHASE_MSGOUT)) {
        !          2422:                NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(tmp));
        !          2423: 
        !          2424:                NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN | 
        !          2425:                    ICR_ASSERT_ACK);
        !          2426:                while (NCR5380_read(STATUS_REG) & SR_REQ);
        !          2427:                NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | 
        !          2428:                    ICR_ASSERT_ATN);
        !          2429:                sink = 0;
        !          2430:                continue;
        !          2431:            }
        !          2432: 
        !          2433:            switch (phase) {
        !          2434:            case PHASE_DATAIN:
        !          2435:            case PHASE_DATAOUT:
        !          2436: #if (NDEBUG & NDEBUG_NO_DATAOUT)
        !          2437:                printk("scsi%d : NDEBUG_NO_DATAOUT set, attempted DATAOUT aborted\n",
        !          2438:                    instance->host_no);
        !          2439:                sink = 1;
        !          2440:                do_abort(instance);
        !          2441:                cmd->result = DID_ERROR  << 16;
        !          2442:                cmd->done(cmd);
        !          2443:                return;
        !          2444: #endif
        !          2445:                /* 
        !          2446:                 * If there is no room left in the current buffer in the
        !          2447:                 * scatter-gather list, move onto the next one.
        !          2448:                 */
        !          2449: 
        !          2450:                if (!cmd->SCp.this_residual && cmd->SCp.buffers_residual) {
        !          2451:                    ++cmd->SCp.buffer;
        !          2452:                    --cmd->SCp.buffers_residual;
        !          2453:                    cmd->SCp.this_residual = cmd->SCp.buffer->length;
        !          2454:                    cmd->SCp.ptr = cmd->SCp.buffer->address;
        !          2455: #if (NDEBUG & NDEBUG_INFORMATION)
        !          2456:                    printk("scsi%d : %d bytes and %d buffers left\n",
        !          2457:                        instance->host_no, cmd->SCp.this_residual,
        !          2458:                        cmd->SCp.buffers_residual);
        !          2459: #endif
        !          2460:                }
        !          2461: 
        !          2462:                /*
        !          2463:                 * The preferred transfer method is going to be 
        !          2464:                 * PSEUDO-DMA for systems that are strictly PIO,
        !          2465:                 * since we can let the hardware do the handshaking.
        !          2466:                 *
        !          2467:                 * For this to work, we need to know the transfersize
        !          2468:                 * ahead of time, since the pseudo-DMA code will sit
        !          2469:                 * in an unconditional loop.
        !          2470:                 */
        !          2471: 
        !          2472: #if defined(PSEUDO_DMA) || defined(REAL_DMA_POLL)
        !          2473:                /* KLL
        !          2474:                 * PSEUDO_DMA is defined here. If this is the g_NCR5380
        !          2475:                 * driver then it will always be defined, so the
        !          2476:                 * FLAG_NO_PSEUDO_DMA is used to inhibit PDMA in the base
        !          2477:                 * NCR5380 case.  I think this is a fairly clean solution.
        !          2478:                 * We supplement these 2 if's with the flag.
        !          2479:                 */
        !          2480: #ifdef NCR5380_dma_xfer_len
        !          2481:                if (!cmd->device->borken &&
        !          2482:                    !(hostdata->flags & FLAG_NO_PSEUDO_DMA) &&
        !          2483:                    (transfersize = NCR5380_dma_xfer_len(instance, cmd)) != 0) {
        !          2484: #else
        !          2485:                transfersize = cmd->transfersize;
        !          2486: 
        !          2487: #ifdef LIMIT_TRANSFERSIZE  /* If we have problems with interrupt service */
        !          2488:                if( transfersize > 512 )
        !          2489:                    transfersize = 512;
        !          2490: #endif  /* LIMIT_TRANSFERSIZE */
        !          2491: 
        !          2492:                if (!cmd->device->borken && transfersize && 
        !          2493:                    !(hostdata->flags & FLAG_NO_PSEUDO_DMA) &&
        !          2494:                    cmd->SCp.this_residual && !(cmd->SCp.this_residual % 
        !          2495:                    transfersize)) {
        !          2496:                     /* Limit transfers to 32K, for xx400 & xx406
        !          2497:                      * pseudoDMA that transfers in 128 bytes blocks. */
        !          2498:                     if (transfersize > 32*1024)
        !          2499:                          transfersize = 32*1024;
        !          2500: #endif
        !          2501:                    len = transfersize;
        !          2502:                    if (NCR5380_transfer_dma(instance, &phase,
        !          2503:                        &len, (unsigned char **) &cmd->SCp.ptr)) {
        !          2504:                        /*
        !          2505:                         * If the watchdog timer fires, all future accesses to this
        !          2506:                         * device will use the polled-IO.
        !          2507:                         */ 
        !          2508:                        printk("scsi%d : switching target %d lun %d to slow handshake\n",
        !          2509:                            instance->host_no, cmd->target, cmd->lun);
        !          2510:                        cmd->device->borken = 1;
        !          2511:                        NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | 
        !          2512:                            ICR_ASSERT_ATN);
        !          2513:                        sink = 1;
        !          2514:                        do_abort(instance);
        !          2515:                        cmd->result = DID_ERROR  << 16;
        !          2516:                        cmd->done(cmd);
        !          2517:                        /* XXX - need to source or sink data here, as appropriate */
        !          2518:                    } else
        !          2519:                        cmd->SCp.this_residual -= transfersize - len;
        !          2520:                } else
        !          2521: #endif /* defined(PSEUDO_DMA) || defined(REAL_DMA_POLL) */
        !          2522:                  NCR5380_transfer_pio(instance, &phase, 
        !          2523:                    (int *) &cmd->SCp.this_residual, (unsigned char **)
        !          2524:                    &cmd->SCp.ptr);
        !          2525:                break;
        !          2526:            case PHASE_MSGIN:
        !          2527:                len = 1;
        !          2528:                data = &tmp;
        !          2529:                NCR5380_transfer_pio(instance, &phase, &len, &data);
        !          2530:                cmd->SCp.Message = tmp;
        !          2531: 
        !          2532:                switch (tmp) {
        !          2533:                /*
        !          2534:                 * Linking lets us reduce the time required to get the 
        !          2535:                 * next command out to the device, hopefully this will
        !          2536:                 * mean we don't waste another revolution due to the delays
        !          2537:                 * required by ARBITRATION and another SELECTION.
        !          2538:                 *
        !          2539:                 * In the current implementation proposal, low level drivers
        !          2540:                 * merely have to start the next command, pointed to by 
        !          2541:                 * next_link, done() is called as with unlinked commands.
        !          2542:                 */
        !          2543: #ifdef LINKED
        !          2544:                case LINKED_CMD_COMPLETE:
        !          2545:                case LINKED_FLG_CMD_COMPLETE:
        !          2546:                    /* Accept message by clearing ACK */
        !          2547:                    NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
        !          2548:                    
        !          2549: #if (NDEBUG & NDEBUG_LINKED) 
        !          2550:                    printk("scsi%d : target %d lun %d linked command complete.\n",
        !          2551:                        instance->host_no, cmd->target, cmd->lun);
        !          2552: #endif
        !          2553:                    /* 
        !          2554:                     * Sanity check : A linked command should only terminate with
        !          2555:                     * one of these messages if there are more linked commands
        !          2556:                     * available.
        !          2557:                     */
        !          2558: 
        !          2559:                    if (!cmd->next_link) {
        !          2560:                         printk("scsi%d : target %d lun %d linked command complete, no next_link\n"
        !          2561:                            instance->host_no, cmd->target, cmd->lun);
        !          2562:                            sink = 1;
        !          2563:                            do_abort (instance);
        !          2564:                            return;
        !          2565:                    }
        !          2566: 
        !          2567:                    initialize_SCp(cmd->next_link);
        !          2568:                    /* The next command is still part of this process */
        !          2569:                    cmd->next_link->tag = cmd->tag;
        !          2570:                    cmd->result = cmd->SCp.Status | (cmd->SCp.Message << 8); 
        !          2571: #if (NDEBUG & NDEBUG_LINKED) 
        !          2572:                    printk("scsi%d : target %d lun %d linked request done, calling scsi_done().\n",
        !          2573:                        instance->host_no, cmd->target, cmd->lun);
        !          2574: #endif
        !          2575: #ifdef NCR5380_STATS
        !          2576:                    collect_stats(hostdata, cmd);
        !          2577: #endif
        !          2578:                    cmd->scsi_done(cmd);
        !          2579:                    cmd = hostdata->connected;
        !          2580:                    break;
        !          2581: #endif /* def LINKED */
        !          2582:                case ABORT:
        !          2583:                case COMMAND_COMPLETE: 
        !          2584:                    /* Accept message by clearing ACK */
        !          2585:                    sink = 1;
        !          2586:                    NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
        !          2587:                    hostdata->connected = NULL;
        !          2588: #if (NDEBUG & NDEBUG_QUEUES)
        !          2589:                    printk("scsi%d : command for target %d, lun %d completed\n",
        !          2590:                        instance->host_no, cmd->target, cmd->lun);
        !          2591: #endif
        !          2592:                    hostdata->busy[cmd->target] &= ~(1 << cmd->lun);
        !          2593: 
        !          2594:                    /* 
        !          2595:                     * I'm not sure what the correct thing to do here is : 
        !          2596:                     * 
        !          2597:                     * If the command that just executed is NOT a request 
        !          2598:                     * sense, the obvious thing to do is to set the result
        !          2599:                     * code to the values of the stored parameters.
        !          2600:                     * 
        !          2601:                     * If it was a REQUEST SENSE command, we need some way 
        !          2602:                     * to differentiate between the failure code of the original
        !          2603:                     * and the failure code of the REQUEST sense - the obvious
        !          2604:                     * case is success, where we fall through and leave the result
        !          2605:                     * code unchanged.
        !          2606:                     * 
        !          2607:                     * The non-obvious place is where the REQUEST SENSE failed 
        !          2608:                     */
        !          2609: 
        !          2610:                    if (cmd->cmnd[0] != REQUEST_SENSE) 
        !          2611:                        cmd->result = cmd->SCp.Status | (cmd->SCp.Message << 8); 
        !          2612:                    else if (cmd->SCp.Status != GOOD)
        !          2613:                        cmd->result = (cmd->result & 0x00ffff) | (DID_ERROR << 16);
        !          2614:                    
        !          2615: #ifdef AUTOSENSE
        !          2616:                    if ((cmd->cmnd[0] != REQUEST_SENSE) && 
        !          2617:                        (cmd->SCp.Status == CHECK_CONDITION)) {
        !          2618: #if (NDEBUG & NDEBUG_AUTOSENSE) 
        !          2619:                        printk("scsi%d : performing request sense\n", 
        !          2620:                            instance->host_no);
        !          2621: #endif
        !          2622:                        cmd->cmnd[0] = REQUEST_SENSE;
        !          2623:                        cmd->cmnd[1] &= 0xe0;
        !          2624:                        cmd->cmnd[2] = 0;
        !          2625:                        cmd->cmnd[3] = 0;
        !          2626:                        cmd->cmnd[4] = sizeof(cmd->sense_buffer);
        !          2627:                        cmd->cmnd[5] = 0;
        !          2628: 
        !          2629:                        cmd->SCp.buffer = NULL;
        !          2630:                        cmd->SCp.buffers_residual = 0;
        !          2631:                        cmd->SCp.ptr = (char *) cmd->sense_buffer;
        !          2632:                        cmd->SCp.this_residual = sizeof(cmd->sense_buffer);
        !          2633: 
        !          2634:                        cli();
        !          2635:                        LIST(cmd,hostdata->issue_queue);
        !          2636:                        cmd->host_scribble = (unsigned char *) 
        !          2637:                            hostdata->issue_queue;
        !          2638:                        hostdata->issue_queue = (Scsi_Cmnd *) cmd;
        !          2639:                        sti();
        !          2640: #if (NDEBUG & NDEBUG_QUEUES)
        !          2641:                        printk("scsi%d : REQUEST SENSE added to head of issue queue\n",instance->host_no);
        !          2642: #endif
        !          2643:                   } else {
        !          2644: #endif /* def AUTOSENSE */
        !          2645: #ifdef NCR5380_STATS
        !          2646:                        collect_stats(hostdata, cmd);
        !          2647: #endif
        !          2648:                        cmd->scsi_done(cmd);
        !          2649:                   }
        !          2650: 
        !          2651:                    NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
        !          2652:                    /* 
        !          2653:                     * Restore phase bits to 0 so an interrupted selection, 
        !          2654:                     * arbitration can resume.
        !          2655:                     */
        !          2656:                    NCR5380_write(TARGET_COMMAND_REG, 0);
        !          2657:                    
        !          2658:                    while ((NCR5380_read(STATUS_REG) & SR_BSY) && !hostdata->connected)
        !          2659:                        barrier();
        !          2660:                    return;
        !          2661:                case MESSAGE_REJECT:
        !          2662:                    /* Accept message by clearing ACK */
        !          2663:                    NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
        !          2664:                    switch (hostdata->last_message) {
        !          2665:                    case HEAD_OF_QUEUE_TAG:
        !          2666:                    case ORDERED_QUEUE_TAG:
        !          2667:                    case SIMPLE_QUEUE_TAG:
        !          2668:                        cmd->device->tagged_queue = 0;
        !          2669:                        hostdata->busy[cmd->target] |= (1 << cmd->lun);
        !          2670:                        break;
        !          2671:                    default:
        !          2672:                        break;
        !          2673:                    }
        !          2674:                case DISCONNECT:
        !          2675:                    /* Accept message by clearing ACK */
        !          2676:                    NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
        !          2677:                    cmd->device->disconnect = 1;
        !          2678:                    cli();
        !          2679:                    LIST(cmd,hostdata->disconnected_queue);
        !          2680:                    cmd->host_scribble = (unsigned char *) 
        !          2681:                        hostdata->disconnected_queue;
        !          2682:                    hostdata->connected = NULL;
        !          2683:                    hostdata->disconnected_queue = cmd;
        !          2684:                    sti();
        !          2685: #if (NDEBUG & NDEBUG_QUEUES)
        !          2686:                    printk("scsi%d : command for target %d lun %d was moved from connected to"
        !          2687:                           "  the disconnected_queue\n", instance->host_no, 
        !          2688:                            cmd->target, cmd->lun);
        !          2689: #endif
        !          2690:                    /* 
        !          2691:                     * Restore phase bits to 0 so an interrupted selection, 
        !          2692:                     * arbitration can resume.
        !          2693:                     */
        !          2694:                    NCR5380_write(TARGET_COMMAND_REG, 0);
        !          2695:  
        !          2696:                    /* Enable reselect interrupts */
        !          2697:                    NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
        !          2698:                    /* Wait for bus free to avoid nasty timeouts */
        !          2699:                    while ((NCR5380_read(STATUS_REG) & SR_BSY) && !hostdata->connected)
        !          2700:                        barrier();
        !          2701: #if 0
        !          2702:                    NCR5380_print_status(instance);
        !          2703: #endif
        !          2704:                    return;
        !          2705:                /* 
        !          2706:                 * The SCSI data pointer is *IMPLICITLY* saved on a disconnect
        !          2707:                 * operation, in violation of the SCSI spec so we can safely 
        !          2708:                 * ignore SAVE/RESTORE pointers calls.
        !          2709:                 *
        !          2710:                 * Unfortunately, some disks violate the SCSI spec and 
        !          2711:                 * don't issue the required SAVE_POINTERS message before
        !          2712:                 * disconnecting, and we have to break spec to remain 
        !          2713:                 * compatible.
        !          2714:                 */
        !          2715:                case SAVE_POINTERS:
        !          2716:                case RESTORE_POINTERS:
        !          2717:                    /* Accept message by clearing ACK */
        !          2718:                    NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
        !          2719:                    break;
        !          2720:                case EXTENDED_MESSAGE:
        !          2721: /* 
        !          2722:  * Extended messages are sent in the following format :
        !          2723:  * Byte        
        !          2724:  * 0           EXTENDED_MESSAGE == 1
        !          2725:  * 1           length (includes one byte for code, doesn't 
        !          2726:  *             include first two bytes)
        !          2727:  * 2           code
        !          2728:  * 3..length+1 arguments
        !          2729:  *
        !          2730:  * Start the extended message buffer with the EXTENDED_MESSAGE
        !          2731:  * byte, since print_msg() wants the whole thing.  
        !          2732:  */
        !          2733:                    extended_msg[0] = EXTENDED_MESSAGE;
        !          2734:                    /* Accept first byte by clearing ACK */
        !          2735:                    NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
        !          2736: 
        !          2737: #if (NDEBUG & NDEBUG_EXTENDED)
        !          2738:                    printk("scsi%d : receiving extended message\n",
        !          2739:                        instance->host_no);
        !          2740: #endif
        !          2741: 
        !          2742:                    len = 2;
        !          2743:                    data = extended_msg + 1;
        !          2744:                    phase = PHASE_MSGIN;
        !          2745:                    NCR5380_transfer_pio(instance, &phase, &len, &data);
        !          2746: 
        !          2747: #if (NDEBUG & NDEBUG_EXTENDED)
        !          2748:                    printk("scsi%d : length=%d, code=0x%02x\n", 
        !          2749:                        instance->host_no, (int) extended_msg[1],
        !          2750:                        (int) extended_msg[2]);
        !          2751: #endif
        !          2752: 
        !          2753:                    if (!len && extended_msg[1] <= 
        !          2754:                        (sizeof (extended_msg) - 1)) {
        !          2755:                        /* Accept third byte by clearing ACK */
        !          2756:                        NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
        !          2757:                        len = extended_msg[1] - 1;
        !          2758:                        data = extended_msg + 3;
        !          2759:                        phase = PHASE_MSGIN;
        !          2760: 
        !          2761:                        NCR5380_transfer_pio(instance, &phase, &len, &data);
        !          2762: 
        !          2763: #if (NDEBUG & NDEBUG_EXTENDED)
        !          2764:                    printk("scsi%d : message received, residual %d\n",
        !          2765:                        instance->host_no, len);
        !          2766: #endif
        !          2767: 
        !          2768:                        switch (extended_msg[2]) {
        !          2769:                        case EXTENDED_SDTR:
        !          2770:                        case EXTENDED_WDTR:
        !          2771:                        case EXTENDED_MODIFY_DATA_POINTER:
        !          2772:                        case EXTENDED_EXTENDED_IDENTIFY:
        !          2773:                            tmp = 0;
        !          2774:                        }
        !          2775:                    } else if (len) {
        !          2776:                        printk("scsi%d: error receiving extended message\n",
        !          2777:                            instance->host_no);
        !          2778:                        tmp = 0;
        !          2779:                    } else {
        !          2780:                        printk("scsi%d: extended message code %02x length %d is too long\n",
        !          2781:                            instance->host_no, extended_msg[2], extended_msg[1]);
        !          2782:                        tmp = 0;
        !          2783:                    }
        !          2784:                /* Fall through to reject message */
        !          2785:                    
        !          2786:                /* 
        !          2787:                 * If we get something weird that we aren't expecting, 
        !          2788:                 * reject it.
        !          2789:                 */
        !          2790:                default:
        !          2791:                    if (!tmp) {
        !          2792:                        printk("scsi%d: rejecting message ", instance->host_no);
        !          2793:                        print_msg (extended_msg);
        !          2794:                        printk("\n");
        !          2795:                    } else if (tmp != EXTENDED_MESSAGE)
        !          2796:                        printk("scsi%d: rejecting unknown message %02x from target %d, lun %d\n",
        !          2797:                            instance->host_no, tmp, cmd->target, cmd->lun);
        !          2798:                    else
        !          2799:                        printk("scsi%d: rejecting unknown extended message code %02x, length %d from target %d, lun %d\n",
        !          2800:                            instance->host_no, extended_msg[1], extended_msg[0], cmd->target, cmd->lun);
        !          2801: 
        !          2802:                    msgout = MESSAGE_REJECT;
        !          2803:                    NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | 
        !          2804:                        ICR_ASSERT_ATN);
        !          2805:                    break;
        !          2806:                } /* switch (tmp) */
        !          2807:                break;
        !          2808:            case PHASE_MSGOUT:
        !          2809:                len = 1;
        !          2810:                data = &msgout;
        !          2811:                hostdata->last_message = msgout;
        !          2812:                NCR5380_transfer_pio(instance, &phase, &len, &data);
        !          2813:                if (msgout == ABORT) {
        !          2814:                    hostdata->busy[cmd->target] &= ~(1 << cmd->lun);
        !          2815:                    hostdata->connected = NULL;
        !          2816:                    cmd->result = DID_ERROR << 16;
        !          2817: #ifdef NCR5380_STATS
        !          2818:                    collect_stats(hostdata, cmd);
        !          2819: #endif
        !          2820:                    cmd->scsi_done(cmd);
        !          2821:                    NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
        !          2822:                    return;
        !          2823:                }
        !          2824:                msgout = NOP;
        !          2825:                break;
        !          2826:            case PHASE_CMDOUT:
        !          2827:                len = cmd->cmd_len;
        !          2828:                data = cmd->cmnd;
        !          2829:                /* 
        !          2830:                 * XXX for performance reasons, on machines with a 
        !          2831:                 * PSEUDO-DMA architecture we should probably 
        !          2832:                 * use the dma transfer function.  
        !          2833:                 */
        !          2834:                NCR5380_transfer_pio(instance, &phase, &len, 
        !          2835:                    &data);
        !          2836: #ifdef USLEEP
        !          2837:                if (!disconnect && should_disconnect(cmd->cmnd[0])) {
        !          2838:                    hostdata->time_expires = jiffies + USLEEP_SLEEP;
        !          2839: #if (NDEBUG & NDEBUG_USLEEP)
        !          2840:                printk("scsi%d : issued command, sleeping until %ul\n", instance->host_no,
        !          2841:                    hostdata->time_expires);
        !          2842: #endif
        !          2843:                    NCR5380_set_timer (instance);
        !          2844:                    return;
        !          2845:                }
        !          2846: #endif /* def USLEEP */
        !          2847:                break;
        !          2848:            case PHASE_STATIN:
        !          2849:                len = 1;
        !          2850:                data = &tmp;
        !          2851:                NCR5380_transfer_pio(instance, &phase, &len, &data);
        !          2852:                cmd->SCp.Status = tmp;
        !          2853:                break;
        !          2854:            default:
        !          2855:                printk("scsi%d : unknown phase\n", instance->host_no);
        !          2856: #ifdef NDEBUG
        !          2857:                NCR5380_print(instance);
        !          2858: #endif
        !          2859:            } /* switch(phase) */
        !          2860:        } /* if (tmp * SR_REQ) */ 
        !          2861: #ifdef USLEEP
        !          2862:        else {
        !          2863:            if (!disconnect && hostdata->time_expires && jiffies > 
        !          2864:                hostdata->time_expires) {
        !          2865:                hostdata->time_expires = jiffies + USLEEP_SLEEP;
        !          2866: #if (NDEBUG & NDEBUG_USLEEP)
        !          2867:                printk("scsi%d : poll timed out, sleeping until %ul\n", instance->host_no,
        !          2868:                    hostdata->time_expires);
        !          2869: #endif
        !          2870:                NCR5380_set_timer (instance);
        !          2871:                return;
        !          2872:            }
        !          2873:        }
        !          2874: #endif
        !          2875:     } /* while (1) */
        !          2876: }
        !          2877: 
        !          2878: /*
        !          2879:  * Function : void NCR5380_reselect (struct Scsi_Host *instance)
        !          2880:  *
        !          2881:  * Purpose : does reselection, initializing the instance->connected 
        !          2882:  *     field to point to the Scsi_Cmnd for which the I_T_L or I_T_L_Q 
        !          2883:  *     nexus has been reestablished,
        !          2884:  *     
        !          2885:  * Inputs : instance - this instance of the NCR5380.
        !          2886:  *
        !          2887:  */
        !          2888: 
        !          2889: 
        !          2890: static void NCR5380_reselect (struct Scsi_Host *instance) {
        !          2891:     NCR5380_local_declare();
        !          2892:     struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *)
        !          2893:        instance->hostdata;
        !          2894:     unsigned char target_mask;
        !          2895:     unsigned char lun, phase;
        !          2896:     int len;
        !          2897: #ifdef SCSI2
        !          2898:     unsigned char tag;
        !          2899: #endif
        !          2900:     unsigned char msg[3];
        !          2901:     unsigned char *data;
        !          2902:     Scsi_Cmnd *tmp = NULL, *prev;
        !          2903:     int abort = 0;
        !          2904:     NCR5380_setup(instance);
        !          2905: 
        !          2906:     /*
        !          2907:      * Disable arbitration, etc. since the host adapter obviously
        !          2908:      * lost, and tell an interrupted NCR5380_select() to restart.
        !          2909:      */
        !          2910: 
        !          2911:     NCR5380_write(MODE_REG, MR_BASE);
        !          2912:     hostdata->restart_select = 1;
        !          2913: 
        !          2914:     target_mask = NCR5380_read(CURRENT_SCSI_DATA_REG) & ~(hostdata->id_mask);
        !          2915: 
        !          2916: #if (NDEBUG & NDEBUG_RESELECTION)
        !          2917:     printk("scsi%d : reselect\n", instance->host_no);
        !          2918: #endif
        !          2919: 
        !          2920:     /* 
        !          2921:      * At this point, we have detected that our SCSI ID is on the bus,
        !          2922:      * SEL is true and BSY was false for at least one bus settle delay
        !          2923:      * (400 ns).
        !          2924:      *
        !          2925:      * We must assert BSY ourselves, until the target drops the SEL
        !          2926:      * signal.
        !          2927:      */
        !          2928: 
        !          2929:     NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_BSY);
        !          2930:     
        !          2931:     while (NCR5380_read(STATUS_REG) & SR_SEL);
        !          2932:     NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
        !          2933: 
        !          2934:     /*
        !          2935:      * Wait for target to go into MSGIN.
        !          2936:      */
        !          2937: 
        !          2938:     while (!(NCR5380_read(STATUS_REG) & SR_REQ));
        !          2939: 
        !          2940:     len = 1;
        !          2941:     data = msg;
        !          2942:     phase = PHASE_MSGIN;
        !          2943:     NCR5380_transfer_pio(instance, &phase, &len, &data);
        !          2944: 
        !          2945: 
        !          2946:     if (!msg[0] & 0x80) {
        !          2947:        printk("scsi%d : expecting IDENTIFY message, got ",
        !          2948:            instance->host_no);
        !          2949:        print_msg(msg);
        !          2950:        abort = 1;
        !          2951:     } else {
        !          2952:        /* Accept message by clearing ACK */
        !          2953:        NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
        !          2954:        lun = (msg[0] & 0x07);
        !          2955: 
        !          2956:        /* 
        !          2957:         * We need to add code for SCSI-II to track which devices have
        !          2958:         * I_T_L_Q nexuses established, and which have simple I_T_L
        !          2959:         * nexuses so we can chose to do additional data transfer.
        !          2960:         */
        !          2961: 
        !          2962: #ifdef SCSI2
        !          2963: #error "SCSI-II tagged queueing is not supported yet"
        !          2964: #endif
        !          2965: 
        !          2966:        /* 
        !          2967:         * Find the command corresponding to the I_T_L or I_T_L_Q  nexus we 
        !          2968:         * just reestablished, and remove it from the disconnected queue.
        !          2969:         */
        !          2970: 
        !          2971: 
        !          2972:        for (tmp = (Scsi_Cmnd *) hostdata->disconnected_queue, prev = NULL; 
        !          2973:            tmp; prev = tmp, tmp = (Scsi_Cmnd *) tmp->host_scribble) 
        !          2974:            if ((target_mask == (1 << tmp->target)) && (lun == tmp->lun)
        !          2975: #ifdef SCSI2
        !          2976:            && (tag == tmp->tag) 
        !          2977: #endif
        !          2978: ) {
        !          2979:            if (prev) {
        !          2980:                REMOVE(prev,prev->host_scribble,tmp,tmp->host_scribble);
        !          2981:                prev->host_scribble = tmp->host_scribble;
        !          2982:            } else {
        !          2983:                REMOVE(-1,hostdata->disconnected_queue,tmp,tmp->host_scribble);
        !          2984:                hostdata->disconnected_queue = (Scsi_Cmnd *) tmp->host_scribble;
        !          2985:            }
        !          2986:            tmp->host_scribble = NULL;
        !          2987:            break;
        !          2988:        }
        !          2989: 
        !          2990:        if (!tmp) {
        !          2991: #ifdef SCSI2
        !          2992:            printk("scsi%d : warning : target bitmask %02x lun %d tag %d not in disconnect_queue.\n",
        !          2993:                    instance->host_no, target_mask, lun, tag);
        !          2994: #else
        !          2995:            printk("scsi%d : warning : target bitmask %02x lun %d not in disconnect_queue.\n",
        !          2996:                    instance->host_no, target_mask, lun);
        !          2997: #endif
        !          2998:        /* 
        !          2999:         * Since we have an established nexus that we can't do anything with,
        !          3000:         * we must abort it.  
        !          3001:         */
        !          3002:        abort = 1;
        !          3003:        }
        !          3004:     }
        !          3005: 
        !          3006:     if (abort) {
        !          3007:        do_abort (instance);
        !          3008:     } else {
        !          3009:        hostdata->connected = tmp;
        !          3010: #if (NDEBUG & NDEBUG_RESELECTION)
        !          3011:        printk("scsi%d : nexus established, target = %d, lun = %d, tag = %d\n",
        !          3012:            instance->host_no, tmp->target, tmp->lun, tmp->tag);
        !          3013: #endif
        !          3014:     }
        !          3015: }
        !          3016: 
        !          3017: /*
        !          3018:  * Function : void NCR5380_dma_complete (struct Scsi_Host *instance)
        !          3019:  *
        !          3020:  * Purpose : called by interrupt handler when DMA finishes or a phase
        !          3021:  *     mismatch occurs (which would finish the DMA transfer).  
        !          3022:  *
        !          3023:  * Inputs : instance - this instance of the NCR5380.
        !          3024:  *
        !          3025:  * Returns : pointer to the Scsi_Cmnd structure for which the I_T_L
        !          3026:  *     nexus has been reestablished, on failure NULL is returned.
        !          3027:  */
        !          3028: 
        !          3029: #ifdef REAL_DMA
        !          3030: static void NCR5380_dma_complete (NCR5380_instance *instance) {
        !          3031:     NCR5380_local_declare();
        !          3032:     struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *
        !          3033:        instance->hostdata);
        !          3034:     int transferred;
        !          3035:     NCR5380_setup(instance);
        !          3036:     
        !          3037:     /*
        !          3038:      * XXX this might not be right.
        !          3039:      *
        !          3040:      * Wait for final byte to transfer, ie wait for ACK to go false.
        !          3041:      *
        !          3042:      * We should use the Last Byte Sent bit, unfortunately this is 
        !          3043:      * not available on the 5380/5381 (only the various CMOS chips)
        !          3044:      */
        !          3045: 
        !          3046:     while (NCR5380_read(BUS_AND_STATUS_REG) & BASR_ACK);
        !          3047: 
        !          3048:     NCR5380_write(MODE_REG, MR_BASE);
        !          3049:     NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
        !          3050: 
        !          3051:     /*
        !          3052:      * The only places we should see a phase mismatch and have to send
        !          3053:      * data from the same set of pointers will be the data transfer
        !          3054:      * phases.  So, residual, requested length are only important here.
        !          3055:      */
        !          3056: 
        !          3057:     if (!(hostdata->connected->SCp.phase & SR_CD)) {
        !          3058:        transferred = instance->dmalen - NCR5380_dma_residual();
        !          3059:        hostdata->connected->SCp.this_residual -= transferred;
        !          3060:        hostdata->connected->SCp.ptr += transferred;
        !          3061:     }
        !          3062: }
        !          3063: #endif /* def REAL_DMA */
        !          3064: 
        !          3065: /*
        !          3066:  * Function : int NCR5380_abort (Scsi_Cmnd *cmd)
        !          3067:  *
        !          3068:  * Purpose : abort a command
        !          3069:  *
        !          3070:  * Inputs : cmd - the Scsi_Cmnd to abort, code - code to set the 
        !          3071:  *     host byte of the result field to, if zero DID_ABORTED is 
        !          3072:  *     used.
        !          3073:  *
        !          3074:  * Returns : 0 - success, -1 on failure.
        !          3075:  *
        !          3076:  * XXX - there is no way to abort the command that is currently 
        !          3077:  *      connected, you have to wait for it to complete.  If this is 
        !          3078:  *      a problem, we could implement longjmp() / setjmp(), setjmp()
        !          3079:  *      called where the loop started in NCR5380_main().
        !          3080:  */
        !          3081: 
        !          3082: #ifndef NCR5380_abort
        !          3083: static
        !          3084: #endif
        !          3085: int NCR5380_abort (Scsi_Cmnd *cmd) {
        !          3086:     NCR5380_local_declare();
        !          3087:     struct Scsi_Host *instance = cmd->host;
        !          3088:     struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *)
        !          3089:        instance->hostdata;
        !          3090:     Scsi_Cmnd *tmp, **prev;
        !          3091: 
        !          3092:     printk("scsi%d : aborting command\n", instance->host_no);
        !          3093:     print_Scsi_Cmnd (cmd);
        !          3094: 
        !          3095:     NCR5380_print_status (instance);
        !          3096: 
        !          3097:     printk("scsi%d : aborting command\n", instance->host_no);
        !          3098:     print_Scsi_Cmnd (cmd);
        !          3099: 
        !          3100:     NCR5380_print_status (instance);
        !          3101: 
        !          3102:     cli();
        !          3103:     NCR5380_setup(instance);
        !          3104: 
        !          3105: #if (NDEBUG & NDEBUG_ABORT)
        !          3106:     printk("scsi%d : abort called\n", instance->host_no);
        !          3107:     printk("        basr 0x%X, sr 0x%X\n", 
        !          3108:           NCR5380_read(BUS_AND_STATUS_REG), NCR5380_read(STATUS_REG));
        !          3109: #endif
        !          3110: 
        !          3111: #if 0
        !          3112: /*
        !          3113:  * Case 1 : If the command is the currently executing command, 
        !          3114:  * we'll set the aborted flag and return control so that 
        !          3115:  * information transfer routine can exit cleanly.
        !          3116:  */
        !          3117: 
        !          3118:     if (hostdata->connected == cmd) {
        !          3119: #if (NDEBUG & NDEBUG_ABORT)
        !          3120:        printk("scsi%d : aborting connected command\n", instance->host_no);
        !          3121: #endif
        !          3122:        hostdata->aborted = 1;
        !          3123: /*
        !          3124:  * We should perform BSY checking, and make sure we haven't slipped
        !          3125:  * into BUS FREE.
        !          3126:  */
        !          3127: 
        !          3128:        NCR5380_write(INITIATOR_COMMAND_REG, ICR_ASSERT_ATN);
        !          3129: /* 
        !          3130:  * Since we can't change phases until we've completed the current 
        !          3131:  * handshake, we have to source or sink a byte of data if the current
        !          3132:  * phase is not MSGOUT.
        !          3133:  */
        !          3134: 
        !          3135: /* 
        !          3136:  * Return control to the executing NCR drive so we can clear the
        !          3137:  * aborted flag and get back into our main loop.
        !          3138:  */ 
        !          3139:  
        !          3140:        return 0;
        !          3141:     }
        !          3142: #endif
        !          3143: 
        !          3144: /* 
        !          3145:  * Case 2 : If the command hasn't been issued yet, we simply remove it 
        !          3146:  *         from the issue queue.
        !          3147:  */
        !          3148: #if (NDEBUG & NDEBUG_ABORT)
        !          3149:     /* KLL */
        !          3150:     printk("scsi%d : abort going into loop.\n", instance->host_no);
        !          3151: #endif
        !          3152:     for (prev = (Scsi_Cmnd **) &(hostdata->issue_queue), 
        !          3153:        tmp = (Scsi_Cmnd *) hostdata->issue_queue;
        !          3154:        tmp; prev = (Scsi_Cmnd **) &(tmp->host_scribble), tmp = 
        !          3155:        (Scsi_Cmnd *) tmp->host_scribble) 
        !          3156:        if (cmd == tmp) {
        !          3157:            REMOVE(5,*prev,tmp,tmp->host_scribble);
        !          3158:            (*prev) = (Scsi_Cmnd *) tmp->host_scribble;
        !          3159:            tmp->host_scribble = NULL;
        !          3160:            tmp->result = DID_ABORT << 16;
        !          3161:            sti();
        !          3162: #if (NDEBUG & NDEBUG_ABORT)
        !          3163:     printk("scsi%d : abort removed command from issue queue.\n", 
        !          3164:        instance->host_no);
        !          3165: #endif
        !          3166:            tmp->done(tmp);
        !          3167:            return SCSI_ABORT_SUCCESS;
        !          3168:        }
        !          3169: #if (NDEBUG  & NDEBUG_ABORT)
        !          3170:     /* KLL */
        !          3171:        else if (prev == tmp) printk("scsi%d : LOOP\n", instance->host_no);
        !          3172: #endif
        !          3173: 
        !          3174: /* 
        !          3175:  * Case 3 : If any commands are connected, we're going to fail the abort
        !          3176:  *         and let the high level SCSI driver retry at a later time or 
        !          3177:  *         issue a reset.
        !          3178:  *
        !          3179:  *         Timeouts, and therefore aborted commands, will be highly unlikely
        !          3180:  *          and handling them cleanly in this situation would make the common
        !          3181:  *         case of noresets less efficient, and would pollute our code.  So,
        !          3182:  *         we fail.
        !          3183:  */
        !          3184: 
        !          3185:     if (hostdata->connected) {
        !          3186:        sti();
        !          3187: #if (NDEBUG & NDEBUG_ABORT)
        !          3188:     printk("scsi%d : abort failed, command connected.\n", instance->host_no);
        !          3189: #endif
        !          3190:        return SCSI_ABORT_NOT_RUNNING;
        !          3191:     }
        !          3192: 
        !          3193: /*
        !          3194:  * Case 4: If the command is currently disconnected from the bus, and 
        !          3195:  *     there are no connected commands, we reconnect the I_T_L or 
        !          3196:  *     I_T_L_Q nexus associated with it, go into message out, and send 
        !          3197:  *      an abort message.
        !          3198:  *
        !          3199:  * This case is especially ugly. In order to reestablish the nexus, we
        !          3200:  * need to call NCR5380_select().  The easiest way to implement this 
        !          3201:  * function was to abort if the bus was busy, and let the interrupt
        !          3202:  * handler triggered on the SEL for reselect take care of lost arbitrations
        !          3203:  * where necessary, meaning interrupts need to be enabled.
        !          3204:  *
        !          3205:  * When interrupts are enabled, the queues may change - so we 
        !          3206:  * can't remove it from the disconnected queue before selecting it
        !          3207:  * because that could cause a failure in hashing the nexus if that 
        !          3208:  * device reselected.
        !          3209:  * 
        !          3210:  * Since the queues may change, we can't use the pointers from when we
        !          3211:  * first locate it.
        !          3212:  *
        !          3213:  * So, we must first locate the command, and if NCR5380_select()
        !          3214:  * succeeds, then issue the abort, relocate the command and remove
        !          3215:  * it from the disconnected queue.
        !          3216:  */
        !          3217: 
        !          3218:     for (tmp = (Scsi_Cmnd *) hostdata->disconnected_queue; tmp; 
        !          3219:        tmp = (Scsi_Cmnd *) tmp->host_scribble) 
        !          3220:        if (cmd == tmp) {
        !          3221:            sti(); 
        !          3222: #if (NDEBUG & NDEBUG_ABORT)
        !          3223:     printk("scsi%d : aborting disconnected command.\n", instance->host_no);
        !          3224: #endif
        !          3225:   
        !          3226:            if (NCR5380_select (instance, cmd, (int) cmd->tag)) 
        !          3227:                return SCSI_ABORT_BUSY;
        !          3228: 
        !          3229: #if (NDEBUG & NDEBUG_ABORT)
        !          3230:     printk("scsi%d : nexus reestablished.\n", instance->host_no);
        !          3231: #endif
        !          3232: 
        !          3233:            do_abort (instance);
        !          3234: 
        !          3235:            cli();
        !          3236:            for (prev = (Scsi_Cmnd **) &(hostdata->disconnected_queue), 
        !          3237:                tmp = (Scsi_Cmnd *) hostdata->disconnected_queue;
        !          3238:                tmp; prev = (Scsi_Cmnd **) &(tmp->host_scribble), tmp = 
        !          3239:                (Scsi_Cmnd *) tmp->host_scribble) 
        !          3240:                    if (cmd == tmp) {
        !          3241:                    REMOVE(5,*prev,tmp,tmp->host_scribble);
        !          3242:                    *prev = (Scsi_Cmnd *) tmp->host_scribble;
        !          3243:                    tmp->host_scribble = NULL;
        !          3244:                    tmp->result = DID_ABORT << 16;
        !          3245:                    sti();
        !          3246:                    tmp->done(tmp);
        !          3247:                    return SCSI_ABORT_SUCCESS;
        !          3248:                }
        !          3249:        }
        !          3250: 
        !          3251: /*
        !          3252:  * Case 5 : If we reached this point, the command was not found in any of 
        !          3253:  *         the queues.
        !          3254:  *
        !          3255:  * We probably reached this point because of an unlikely race condition
        !          3256:  * between the command completing successfully and the abortion code,
        !          3257:  * so we won't panic, but we will notify the user in case something really
        !          3258:  * broke.
        !          3259:  */
        !          3260: 
        !          3261:     sti();
        !          3262:     printk("scsi%d : warning : SCSI command probably completed successfully\n"
        !          3263:           "         before abortion\n", instance->host_no); 
        !          3264:     return SCSI_ABORT_NOT_RUNNING;
        !          3265: }
        !          3266: 
        !          3267: 
        !          3268: /* 
        !          3269:  * Function : int NCR5380_reset (Scsi_Cmnd *cmd, unsigned int reset_flags)
        !          3270:  * 
        !          3271:  * Purpose : reset the SCSI bus.
        !          3272:  *
        !          3273:  * Returns : SCSI_RESET_WAKEUP
        !          3274:  *
        !          3275:  */ 
        !          3276: 
        !          3277: #ifndef NCR5380_reset
        !          3278: static
        !          3279: #endif
        !          3280: int NCR5380_reset (Scsi_Cmnd *cmd, unsigned int dummy) {
        !          3281:     NCR5380_local_declare();
        !          3282:     NCR5380_setup(cmd->host);
        !          3283: 
        !          3284:     NCR5380_print_status (cmd->host);
        !          3285:     do_reset (cmd->host);
        !          3286: 
        !          3287:     return SCSI_RESET_WAKEUP;
        !          3288: }
        !          3289: 

unix.superglobalmegacorp.com

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