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