|
|
1.1 ! root 1: /* aha152x.c -- Adaptec AHA-152x driver ! 2: * Author: Juergen E. Fischer, [email protected] ! 3: * Copyright 1993, 1994, 1995 Juergen E. Fischer ! 4: * ! 5: * ! 6: * This driver is based on ! 7: * fdomain.c -- Future Domain TMC-16x0 driver ! 8: * which is ! 9: * Copyright 1992, 1993 Rickard E. Faith ([email protected]) ! 10: * ! 11: * ! 12: * This program is free software; you can redistribute it and/or modify it ! 13: * under the terms of the GNU General Public License as published by the ! 14: * Free Software Foundation; either version 2, or (at your option) any ! 15: * later version. ! 16: * ! 17: * This program is distributed in the hope that it will be useful, but ! 18: * WITHOUT ANY WARRANTY; without even the implied warranty of ! 19: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ! 20: * General Public License for more details. ! 21: * ! 22: * ! 23: * $Id: aha152x.c,v 1.1.1.1 1997/02/25 21:27:46 thomas Exp $ ! 24: * ! 25: * $Log: aha152x.c,v $ ! 26: * Revision 1.1.1.1 1997/02/25 21:27:46 thomas ! 27: * Initial source ! 28: * ! 29: * Revision 1.1.1.1 1996/10/30 01:40:01 thomas ! 30: * Imported from UK22 ! 31: * ! 32: * Revision 1.1 1996/03/25 20:25:17 goel ! 33: * Linux driver merge. ! 34: * ! 35: * Revision 1.14 1996/01/17 15:11:20 fischer ! 36: * - fixed lockup in MESSAGE IN phase after reconnection ! 37: * ! 38: * Revision 1.13 1996/01/09 02:15:53 fischer ! 39: * - some cleanups ! 40: * - moved request_irq behind controller initialization ! 41: * (to avoid spurious interrupts) ! 42: * ! 43: * Revision 1.12 1995/12/16 12:26:07 fischer ! 44: * - barrier()'s added ! 45: * - configurable RESET delay added ! 46: * ! 47: * Revision 1.11 1995/12/06 21:18:35 fischer ! 48: * - some minor updates ! 49: * ! 50: * Revision 1.10 1995/07/22 19:18:45 fischer ! 51: * - support for 2 controllers ! 52: * - started synchronous data transfers (not working yet) ! 53: * ! 54: * Revision 1.9 1995/03/18 09:20:24 root ! 55: * - patches for PCMCIA and modules ! 56: * ! 57: * Revision 1.8 1995/01/21 22:07:19 root ! 58: * - snarf_region => request_region ! 59: * - aha152x_intr interface change ! 60: * ! 61: * Revision 1.7 1995/01/02 23:19:36 root ! 62: * - updated COMMAND_SIZE to cmd_len ! 63: * - changed sti() to restore_flags() ! 64: * - fixed some #ifdef which generated warnings ! 65: * ! 66: * Revision 1.6 1994/11/24 20:35:27 root ! 67: * - problem with odd number of bytes in fifo fixed ! 68: * ! 69: * Revision 1.5 1994/10/30 14:39:56 root ! 70: * - abort code fixed ! 71: * - debugging improved ! 72: * ! 73: * Revision 1.4 1994/09/12 11:33:01 root ! 74: * - irqaction to request_irq ! 75: * - abortion updated ! 76: * ! 77: * Revision 1.3 1994/08/04 13:53:05 root ! 78: * - updates for mid-level-driver changes ! 79: * - accept unexpected BUSFREE phase as error condition ! 80: * - parity check now configurable ! 81: * ! 82: * Revision 1.2 1994/07/03 12:56:36 root ! 83: * - cleaned up debugging code ! 84: * - more tweaking on reset delays ! 85: * - updated abort/reset code (pretty untested...) ! 86: * ! 87: * Revision 1.1 1994/05/28 21:18:49 root ! 88: * - update for mid-level interface change (abort-reset) ! 89: * - delays after resets adjusted for some slow devices ! 90: * ! 91: * Revision 1.0 1994/03/25 12:52:00 root ! 92: * - Fixed "more data than expected" problem ! 93: * - added new BIOS signatures ! 94: * ! 95: * Revision 0.102 1994/01/31 20:44:12 root ! 96: * - minor changes in insw/outsw handling ! 97: * ! 98: * Revision 0.101 1993/12/13 01:16:27 root ! 99: * - fixed STATUS phase (non-GOOD stati were dropped sometimes; ! 100: * fixes problems with CD-ROM sector size detection & media change) ! 101: * ! 102: * Revision 0.100 1993/12/10 16:58:47 root ! 103: * - fix for unsuccessful selections in case of non-continuous id assignments ! 104: * on the scsi bus. ! 105: * ! 106: * Revision 0.99 1993/10/24 16:19:59 root ! 107: * - fixed DATA IN (rare read errors gone) ! 108: * ! 109: * Revision 0.98 1993/10/17 12:54:44 root ! 110: * - fixed some recent fixes (shame on me) ! 111: * - moved initialization of scratch area to aha152x_queue ! 112: * ! 113: * Revision 0.97 1993/10/09 18:53:53 root ! 114: * - DATA IN fixed. Rarely left data in the fifo. ! 115: * ! 116: * Revision 0.96 1993/10/03 00:53:59 root ! 117: * - minor changes on DATA IN ! 118: * ! 119: * Revision 0.95 1993/09/24 10:36:01 root ! 120: * - change handling of MSGI after reselection ! 121: * - fixed sti/cli ! 122: * - minor changes ! 123: * ! 124: * Revision 0.94 1993/09/18 14:08:22 root ! 125: * - fixed bug in multiple outstanding command code ! 126: * - changed detection ! 127: * - support for kernel command line configuration ! 128: * - reset corrected ! 129: * - changed message handling ! 130: * ! 131: * Revision 0.93 1993/09/15 20:41:19 root ! 132: * - fixed bugs with multiple outstanding commands ! 133: * ! 134: * Revision 0.92 1993/09/13 02:46:33 root ! 135: * - multiple outstanding commands work (no problems with IBM drive) ! 136: * ! 137: * Revision 0.91 1993/09/12 20:51:46 root ! 138: * added multiple outstanding commands ! 139: * (some problem with this $%&? IBM device remain) ! 140: * ! 141: * Revision 0.9 1993/09/12 11:11:22 root ! 142: * - corrected auto-configuration ! 143: * - changed the auto-configuration (added some '#define's) ! 144: * - added support for dis-/reconnection ! 145: * ! 146: * Revision 0.8 1993/09/06 23:09:39 root ! 147: * - added support for the drive activity light ! 148: * - minor changes ! 149: * ! 150: * Revision 0.7 1993/09/05 14:30:15 root ! 151: * - improved phase detection ! 152: * - now using the new snarf_region code of 0.99pl13 ! 153: * ! 154: * Revision 0.6 1993/09/02 11:01:38 root ! 155: * first public release; added some signatures and biosparam() ! 156: * ! 157: * Revision 0.5 1993/08/30 10:23:30 root ! 158: * fixed timing problems with my IBM drive ! 159: * ! 160: * Revision 0.4 1993/08/29 14:06:52 root ! 161: * fixed some problems with timeouts due incomplete commands ! 162: * ! 163: * Revision 0.3 1993/08/28 15:55:03 root ! 164: * writing data works too. mounted and worked on a dos partition ! 165: * ! 166: * Revision 0.2 1993/08/27 22:42:07 root ! 167: * reading data works. Mounted a msdos partition. ! 168: * ! 169: * Revision 0.1 1993/08/25 13:38:30 root ! 170: * first "damn thing doesn't work" version ! 171: * ! 172: * Revision 0.0 1993/08/14 19:54:25 root ! 173: * empty function bodies; detect() works. ! 174: * ! 175: * ! 176: ************************************************************************** ! 177: ! 178: ! 179: ! 180: DESCRIPTION: ! 181: ! 182: This is the Linux low-level SCSI driver for Adaptec AHA-1520/1522 ! 183: SCSI host adapters. ! 184: ! 185: ! 186: PER-DEFINE CONFIGURABLE OPTIONS: ! 187: ! 188: AUTOCONF: ! 189: use configuration the controller reports (only 152x) ! 190: ! 191: SKIP_BIOSTEST: ! 192: Don't test for BIOS signature (AHA-1510 or disabled BIOS) ! 193: ! 194: SETUP0 { IOPORT, IRQ, SCSI_ID, RECONNECT, PARITY, SYNCHRONOUS, DELAY }: ! 195: override for the first controller ! 196: ! 197: SETUP1 { IOPORT, IRQ, SCSI_ID, RECONNECT, PARITY, SYNCHRONOUS, DELAY }: ! 198: override for the second controller ! 199: ! 200: ! 201: LILO COMMAND LINE OPTIONS: ! 202: ! 203: aha152x=<IOPORT>[,<IRQ>[,<SCSI-ID>[,<RECONNECT>[,<PARITY>[,<SYNCHRONOUS>[,<DELAY>]]]]]] ! 204: ! 205: The normal configuration can be overridden by specifying a command line. ! 206: When you do this, the BIOS test is skipped. Entered values have to be ! 207: valid (known). Don't use values that aren't supported under normal operation. ! 208: If you think that you need other values: contact me. For two controllers ! 209: use the aha152x statement twice. ! 210: ! 211: ! 212: REFERENCES USED: ! 213: ! 214: "AIC-6260 SCSI Chip Specification", Adaptec Corporation. ! 215: ! 216: "SCSI COMPUTER SYSTEM INTERFACE - 2 (SCSI-2)", X3T9.2/86-109 rev. 10h ! 217: ! 218: "Writing a SCSI device driver for Linux", Rik Faith ([email protected]) ! 219: ! 220: "Kernel Hacker's Guide", Michael K. Johnson ([email protected]) ! 221: ! 222: "Adaptec 1520/1522 User's Guide", Adaptec Corporation. ! 223: ! 224: Michael K. Johnson ([email protected]) ! 225: ! 226: Drew Eckhardt ([email protected]) ! 227: ! 228: Eric Youngdale ([email protected]) ! 229: ! 230: special thanks to Eric Youngdale for the free(!) supplying the ! 231: documentation on the chip. ! 232: ! 233: **************************************************************************/ ! 234: ! 235: #ifdef PCMCIA ! 236: #define MODULE ! 237: #endif ! 238: ! 239: #include <linux/module.h> ! 240: ! 241: #ifdef PCMCIA ! 242: #undef MODULE ! 243: #endif ! 244: ! 245: #include <linux/sched.h> ! 246: #include <asm/io.h> ! 247: #include <linux/blk.h> ! 248: #include "scsi.h" ! 249: #include "sd.h" ! 250: #include "hosts.h" ! 251: #include "constants.h" ! 252: #include <asm/system.h> ! 253: #include <linux/errno.h> ! 254: #include <linux/string.h> ! 255: #include <linux/wait.h> ! 256: #include <linux/ioport.h> ! 257: #include <linux/proc_fs.h> ! 258: ! 259: #include "aha152x.h" ! 260: #include <linux/stat.h> ! 261: ! 262: struct proc_dir_entry proc_scsi_aha152x = { ! 263: PROC_SCSI_AHA152X, 7, "aha152x", ! 264: S_IFDIR | S_IRUGO | S_IXUGO, 2 ! 265: }; ! 266: ! 267: /* DEFINES */ ! 268: ! 269: #ifdef MACH ! 270: #define AUTOCONF ! 271: #endif ! 272: ! 273: /* For PCMCIA cards, always use AUTOCONF */ ! 274: #if defined(PCMCIA) || defined(MODULE) ! 275: #if !defined(AUTOCONF) ! 276: #define AUTOCONF ! 277: #endif ! 278: #endif ! 279: ! 280: #if !defined(AUTOCONF) && !defined(SETUP0) ! 281: #error define AUTOCONF or SETUP0 ! 282: #endif ! 283: ! 284: #if defined(DEBUG_AHA152X) ! 285: ! 286: #undef SKIP_PORTS /* don't display ports */ ! 287: ! 288: #undef DEBUG_QUEUE /* debug queue() */ ! 289: #undef DEBUG_RESET /* debug reset() */ ! 290: #undef DEBUG_INTR /* debug intr() */ ! 291: #undef DEBUG_SELECTION /* debug selection part in intr() */ ! 292: #undef DEBUG_MSGO /* debug message out phase in intr() */ ! 293: #undef DEBUG_MSGI /* debug message in phase in intr() */ ! 294: #undef DEBUG_STATUS /* debug status phase in intr() */ ! 295: #undef DEBUG_CMD /* debug command phase in intr() */ ! 296: #undef DEBUG_DATAI /* debug data in phase in intr() */ ! 297: #undef DEBUG_DATAO /* debug data out phase in intr() */ ! 298: #undef DEBUG_ABORT /* debug abort() */ ! 299: #undef DEBUG_DONE /* debug done() */ ! 300: #undef DEBUG_BIOSPARAM /* debug biosparam() */ ! 301: ! 302: #undef DEBUG_RACE /* debug race conditions */ ! 303: #undef DEBUG_PHASES /* debug phases (useful to trace) */ ! 304: #undef DEBUG_QUEUES /* debug reselection */ ! 305: ! 306: /* recently used for debugging */ ! 307: #if 0 ! 308: #endif ! 309: ! 310: #define DEBUG_SELECTION ! 311: #define DEBUG_PHASES ! 312: #define DEBUG_RESET ! 313: #define DEBUG_ABORT ! 314: ! 315: #define DEBUG_DEFAULT (debug_reset|debug_abort) ! 316: ! 317: #endif ! 318: ! 319: /* END OF DEFINES */ ! 320: ! 321: extern long loops_per_sec; ! 322: ! 323: #define DELAY_DEFAULT 100 ! 324: ! 325: /* some additional "phases" for getphase() */ ! 326: #define P_BUSFREE 1 ! 327: #define P_PARITY 2 ! 328: ! 329: /* possible irq range */ ! 330: #define IRQ_MIN 9 ! 331: #define IRQ_MAX 12 ! 332: #define IRQS IRQ_MAX-IRQ_MIN+1 ! 333: ! 334: enum { ! 335: not_issued = 0x0001, ! 336: in_selection = 0x0002, ! 337: disconnected = 0x0004, ! 338: aborted = 0x0008, ! 339: sent_ident = 0x0010, ! 340: in_other = 0x0020, ! 341: in_sync = 0x0040, ! 342: sync_ok = 0x0080, ! 343: }; ! 344: ! 345: /* set by aha152x_setup according to the command line */ ! 346: static int setup_count=0; ! 347: static struct aha152x_setup { ! 348: int io_port; ! 349: int irq; ! 350: int scsiid; ! 351: int reconnect; ! 352: int parity; ! 353: int synchronous; ! 354: int delay; ! 355: #ifdef DEBUG_AHA152X ! 356: int debug; ! 357: #endif ! 358: char *conf; ! 359: } setup[2]; ! 360: ! 361: static struct Scsi_Host *aha152x_host[IRQS]; ! 362: ! 363: #define HOSTDATA(shpnt) ((struct aha152x_hostdata *) &shpnt->hostdata) ! 364: #define CURRENT_SC (HOSTDATA(shpnt)->current_SC) ! 365: #define ISSUE_SC (HOSTDATA(shpnt)->issue_SC) ! 366: #define DISCONNECTED_SC (HOSTDATA(shpnt)->disconnected_SC) ! 367: #define DELAY (HOSTDATA(shpnt)->delay) ! 368: #define SYNCRATE (HOSTDATA(shpnt)->syncrate[CURRENT_SC->target]) ! 369: #define MSG(i) (HOSTDATA(shpnt)->message[i]) ! 370: #define MSGLEN (HOSTDATA(shpnt)->message_len) ! 371: #define ADDMSG(x) (MSG(MSGLEN++)=x) ! 372: ! 373: struct aha152x_hostdata { ! 374: Scsi_Cmnd *issue_SC; ! 375: Scsi_Cmnd *current_SC; ! 376: Scsi_Cmnd *disconnected_SC; ! 377: int aborting; ! 378: int abortion_complete; ! 379: int abort_result; ! 380: int commands; ! 381: ! 382: int reconnect; ! 383: int parity; ! 384: int synchronous; ! 385: int delay; ! 386: ! 387: unsigned char syncrate[8]; ! 388: ! 389: unsigned char message[256]; ! 390: int message_len; ! 391: ! 392: #ifdef DEBUG_AHA152X ! 393: int debug; ! 394: #endif ! 395: }; ! 396: ! 397: void aha152x_intr(int irq, struct pt_regs *); ! 398: void aha152x_done(struct Scsi_Host *shpnt, int error); ! 399: void aha152x_setup(char *str, int *ints); ! 400: int aha152x_checksetup(struct aha152x_setup *setup); ! 401: ! 402: static void aha152x_reset_ports(struct Scsi_Host *shpnt); ! 403: static void aha152x_panic(struct Scsi_Host *shpnt, char *msg); ! 404: ! 405: static void disp_ports(struct Scsi_Host *shpnt); ! 406: static void show_command(Scsi_Cmnd *ptr); ! 407: static void show_queues(struct Scsi_Host *shpnt); ! 408: static void disp_enintr(struct Scsi_Host *shpnt); ! 409: ! 410: #if defined(DEBUG_RACE) ! 411: static void enter_driver(const char *); ! 412: static void leave_driver(const char *); ! 413: #endif ! 414: ! 415: /* possible i/o addresses for the AIC-6260 */ ! 416: static unsigned short ports[] = ! 417: { ! 418: 0x340, /* default first */ ! 419: 0x140 ! 420: }; ! 421: #define PORT_COUNT (sizeof(ports) / sizeof(unsigned short)) ! 422: ! 423: #if !defined(SKIP_BIOSTEST) ! 424: /* possible locations for the Adaptec BIOS */ ! 425: static void *addresses[] = ! 426: { ! 427: (void *) 0xdc000, /* default first */ ! 428: (void *) 0xc8000, ! 429: (void *) 0xcc000, ! 430: (void *) 0xd0000, ! 431: (void *) 0xd4000, ! 432: (void *) 0xd8000, ! 433: (void *) 0xe0000, ! 434: (void *) 0xeb800, /* VTech Platinum SMP */ ! 435: (void *) 0xf0000, ! 436: }; ! 437: #define ADDRESS_COUNT (sizeof(addresses) / sizeof(void *)) ! 438: ! 439: /* signatures for various AIC-6[23]60 based controllers. ! 440: The point in detecting signatures is to avoid useless ! 441: and maybe harmful probes on ports. I'm not sure that ! 442: all listed boards pass auto-configuration. For those ! 443: which fail the BIOS signature is obsolete, because ! 444: user intervention to supply the configuration is ! 445: needed anyway. */ ! 446: static struct signature { ! 447: char *signature; ! 448: int sig_offset; ! 449: int sig_length; ! 450: } signatures[] = ! 451: { ! 452: { "Adaptec AHA-1520 BIOS", 0x102e, 21 }, /* Adaptec 152x */ ! 453: { "Adaptec ASW-B626 BIOS", 0x1029, 21 }, /* on-board controller */ ! 454: { "Adaptec BIOS: ASW-B626", 0x0f, 22 }, /* on-board controller */ ! 455: { "Adaptec ASW-B626 S2", 0x2e6c, 19 }, /* on-board controller */ ! 456: { "Adaptec BIOS:AIC-6360", 0xc, 21 }, /* on-board controller */ ! 457: { "ScsiPro SP-360 BIOS", 0x2873, 19 }, /* ScsiPro-Controller */ ! 458: { "GA-400 LOCAL BUS SCSI BIOS", 0x102e, 26 }, /* Gigabyte Local-Bus-SCSI */ ! 459: { "Adaptec BIOS:AVA-282X", 0xc, 21 }, /* Adaptec 282x */ ! 460: { "Adaptec IBM Dock II SCSI", 0x2edd, 24 }, /* IBM Thinkpad Dock II */ ! 461: { "Adaptec BIOS:AHA-1532P", 0x1c, 22 }, /* IBM Thinkpad Dock II SCSI */ ! 462: }; ! 463: #define SIGNATURE_COUNT (sizeof(signatures) / sizeof(struct signature)) ! 464: #endif ! 465: ! 466: ! 467: static void do_pause(unsigned amount) /* Pause for amount*10 milliseconds */ ! 468: { ! 469: unsigned long the_time = jiffies + amount; /* 0.01 seconds per jiffy */ ! 470: ! 471: while (jiffies < the_time) ! 472: barrier(); ! 473: } ! 474: ! 475: /* ! 476: * queue services: ! 477: */ ! 478: static inline void append_SC(Scsi_Cmnd **SC, Scsi_Cmnd *new_SC) ! 479: { ! 480: Scsi_Cmnd *end; ! 481: ! 482: new_SC->host_scribble = (unsigned char *) NULL; ! 483: if(!*SC) ! 484: *SC=new_SC; ! 485: else ! 486: { ! 487: for(end=*SC; end->host_scribble; end = (Scsi_Cmnd *) end->host_scribble) ! 488: ; ! 489: end->host_scribble = (unsigned char *) new_SC; ! 490: } ! 491: } ! 492: ! 493: static inline Scsi_Cmnd *remove_first_SC(Scsi_Cmnd **SC) ! 494: { ! 495: Scsi_Cmnd *ptr; ! 496: ! 497: ptr=*SC; ! 498: if(ptr) ! 499: *SC= (Scsi_Cmnd *) (*SC)->host_scribble; ! 500: return ptr; ! 501: } ! 502: ! 503: static inline Scsi_Cmnd *remove_SC(Scsi_Cmnd **SC, int target, int lun) ! 504: { ! 505: Scsi_Cmnd *ptr, *prev; ! 506: ! 507: for(ptr=*SC, prev=NULL; ! 508: ptr && ((ptr->target!=target) || (ptr->lun!=lun)); ! 509: prev = ptr, ptr = (Scsi_Cmnd *) ptr->host_scribble) ! 510: ; ! 511: ! 512: if(ptr) ! 513: if(prev) ! 514: prev->host_scribble = ptr->host_scribble; ! 515: else ! 516: *SC= (Scsi_Cmnd *) ptr->host_scribble; ! 517: return ptr; ! 518: } ! 519: ! 520: /* ! 521: * read inbound byte and wait for ACK to get low ! 522: */ ! 523: static void make_acklow(struct Scsi_Host *shpnt) ! 524: { ! 525: SETPORT(SXFRCTL0, CH1|SPIOEN); ! 526: GETPORT(SCSIDAT); ! 527: SETPORT(SXFRCTL0, CH1); ! 528: ! 529: while(TESTHI(SCSISIG, ACKI)) ! 530: barrier(); ! 531: } ! 532: ! 533: /* ! 534: * detect current phase more reliable: ! 535: * phase is valid, when the target asserts REQ after we've deasserted ACK. ! 536: * ! 537: * return value is a valid phase or an error code. ! 538: * ! 539: * errorcodes: ! 540: * P_BUSFREE BUS FREE phase detected ! 541: * P_PARITY parity error in DATA phase ! 542: */ ! 543: static int getphase(struct Scsi_Host *shpnt) ! 544: { ! 545: int phase, sstat1; ! 546: ! 547: while(1) ! 548: { ! 549: do ! 550: { ! 551: while(!((sstat1 = GETPORT(SSTAT1)) & (BUSFREE|SCSIRSTI|REQINIT))) ! 552: barrier(); ! 553: if(sstat1 & BUSFREE) ! 554: return P_BUSFREE; ! 555: if(sstat1 & SCSIRSTI) ! 556: { ! 557: printk("aha152x: RESET IN\n"); ! 558: SETPORT(SSTAT1, SCSIRSTI); ! 559: } ! 560: } ! 561: while(TESTHI(SCSISIG, ACKI) || TESTLO(SSTAT1, REQINIT)); ! 562: ! 563: SETPORT(SSTAT1, CLRSCSIPERR); ! 564: ! 565: phase = GETPORT(SCSISIG) & P_MASK ; ! 566: ! 567: if(TESTHI(SSTAT1, SCSIPERR)) ! 568: { ! 569: if((phase & (CDO|MSGO))==0) /* DATA phase */ ! 570: return P_PARITY; ! 571: ! 572: make_acklow(shpnt); ! 573: } ! 574: else ! 575: return phase; ! 576: } ! 577: } ! 578: ! 579: /* called from init/main.c */ ! 580: void aha152x_setup(char *str, int *ints) ! 581: { ! 582: if(setup_count>2) ! 583: panic("aha152x: you can only configure up to two controllers\n"); ! 584: ! 585: setup[setup_count].conf = str; ! 586: setup[setup_count].io_port = ints[0] >= 1 ? ints[1] : 0x340; ! 587: setup[setup_count].irq = ints[0] >= 2 ? ints[2] : 11; ! 588: setup[setup_count].scsiid = ints[0] >= 3 ? ints[3] : 7; ! 589: setup[setup_count].reconnect = ints[0] >= 4 ? ints[4] : 1; ! 590: setup[setup_count].parity = ints[0] >= 5 ? ints[5] : 1; ! 591: setup[setup_count].synchronous = ints[0] >= 6 ? ints[6] : 0 /* FIXME: 1 */; ! 592: setup[setup_count].delay = ints[0] >= 7 ? ints[7] : DELAY_DEFAULT; ! 593: #ifdef DEBUG_AHA152X ! 594: setup[setup_count].debug = ints[0] >= 8 ? ints[8] : DEBUG_DEFAULT; ! 595: if(ints[0]>8) ! 596: { ! 597: printk("aha152x: usage: aha152x=<IOBASE>[,<IRQ>[,<SCSI ID>" ! 598: "[,<RECONNECT>[,<PARITY>[,<SYNCHRONOUS>[,<DELAY>[,<DEBUG>]]]]]]]\n"); ! 599: #else ! 600: if(ints[0]>7) ! 601: { ! 602: printk("aha152x: usage: aha152x=<IOBASE>[,<IRQ>[,<SCSI ID>" ! 603: "[,<RECONNECT>[,<PARITY>[,<SYNCHRONOUS>[,<DELAY>]]]]]]\n"); ! 604: #endif ! 605: } ! 606: else ! 607: setup_count++; ! 608: } ! 609: ! 610: /* ! 611: Test, if port_base is valid. ! 612: */ ! 613: static int aha152x_porttest(int io_port) ! 614: { ! 615: int i; ! 616: ! 617: if(check_region(io_port, IO_RANGE)) ! 618: return 0; ! 619: ! 620: SETPORT(io_port+O_DMACNTRL1, 0); /* reset stack pointer */ ! 621: for(i=0; i<16; i++) ! 622: SETPORT(io_port+O_STACK, i); ! 623: ! 624: SETPORT(io_port+O_DMACNTRL1, 0); /* reset stack pointer */ ! 625: for(i=0; i<16 && GETPORT(io_port+O_STACK)==i; i++) ! 626: ; ! 627: ! 628: return(i==16); ! 629: } ! 630: ! 631: int aha152x_checksetup(struct aha152x_setup *setup) ! 632: { ! 633: int i; ! 634: ! 635: #ifndef PCMCIA ! 636: for(i=0; i<PORT_COUNT && (setup->io_port != ports[i]); i++) ! 637: ; ! 638: ! 639: if(i==PORT_COUNT) ! 640: return 0; ! 641: #endif ! 642: ! 643: if(!aha152x_porttest(setup->io_port)) ! 644: return 0; ! 645: ! 646: if((setup->irq < IRQ_MIN) && (setup->irq > IRQ_MAX)) ! 647: return 0; ! 648: ! 649: if((setup->scsiid < 0) || (setup->scsiid > 7)) ! 650: return 0; ! 651: ! 652: if((setup->reconnect < 0) || (setup->reconnect > 1)) ! 653: return 0; ! 654: ! 655: if((setup->parity < 0) || (setup->parity > 1)) ! 656: return 0; ! 657: ! 658: if((setup->synchronous < 0) || (setup->synchronous > 1)) ! 659: return 0; ! 660: ! 661: return 1; ! 662: } ! 663: ! 664: ! 665: int aha152x_detect(Scsi_Host_Template * tpnt) ! 666: { ! 667: int i, j, ok; ! 668: #if defined(AUTOCONF) ! 669: aha152x_config conf; ! 670: #endif ! 671: ! 672: tpnt->proc_dir = &proc_scsi_aha152x; ! 673: ! 674: for(i=0; i<IRQS; i++) ! 675: aha152x_host[i] = (struct Scsi_Host *) NULL; ! 676: ! 677: if(setup_count) ! 678: { ! 679: printk("aha152x: processing commandline: "); ! 680: ! 681: for(i=0; i<setup_count; i++) ! 682: if(!aha152x_checksetup(&setup[i])) ! 683: { ! 684: printk("\naha152x: %s\n", setup[i].conf); ! 685: printk("aha152x: invalid line (controller=%d)\n", i+1); ! 686: } ! 687: ! 688: printk("ok\n"); ! 689: } ! 690: ! 691: #ifdef SETUP0 ! 692: if(setup_count<2) ! 693: { ! 694: struct aha152x_setup override = SETUP0; ! 695: ! 696: if(setup_count==0 || (override.io_port != setup[0].io_port)) ! 697: if(!aha152x_checksetup(&override)) ! 698: { ! 699: printk("\naha152x: SETUP0 (0x%x, %d, %d, %d, %d, %d, %d) invalid\n", ! 700: override.io_port, ! 701: override.irq, ! 702: override.scsiid, ! 703: override.reconnect, ! 704: override.parity, ! 705: override.synchronous, ! 706: override.delay); ! 707: } ! 708: else ! 709: setup[setup_count++] = override; ! 710: } ! 711: #endif ! 712: ! 713: #ifdef SETUP1 ! 714: if(setup_count<2) ! 715: { ! 716: struct aha152x_setup override = SETUP1; ! 717: ! 718: if(setup_count==0 || (override.io_port != setup[0].io_port)) ! 719: if(!aha152x_checksetup(&override)) ! 720: { ! 721: printk("\naha152x: SETUP1 (0x%x, %d, %d, %d, %d, %d, %d) invalid\n", ! 722: override.io_port, ! 723: override.irq, ! 724: override.scsiid, ! 725: override.reconnect, ! 726: override.parity, ! 727: override.synchronous, ! 728: override.delay); ! 729: } ! 730: else ! 731: setup[setup_count++] = override; ! 732: } ! 733: #endif ! 734: ! 735: #if defined(AUTOCONF) ! 736: if(setup_count<2) ! 737: { ! 738: #if !defined(SKIP_BIOSTEST) ! 739: ok=0; ! 740: for(i=0; i < ADDRESS_COUNT && !ok; i++) ! 741: for(j=0; (j < SIGNATURE_COUNT) && !ok; j++) ! 742: ok=!memcmp((void *) addresses[i]+signatures[j].sig_offset, ! 743: (void *) signatures[j].signature, ! 744: (int) signatures[j].sig_length); ! 745: ! 746: if(!ok && setup_count==0) ! 747: return 0; ! 748: ! 749: printk("aha152x: BIOS test: passed, "); ! 750: #else ! 751: printk("aha152x: "); ! 752: #endif /* !SKIP_BIOSTEST */ ! 753: ! 754: for(i=0; i<PORT_COUNT && setup_count<2; i++) ! 755: { ! 756: if((setup_count==1) && (setup[0].io_port == ports[i])) ! 757: continue; ! 758: ! 759: if(aha152x_porttest(ports[i])) ! 760: { ! 761: setup[setup_count].io_port = ports[i]; ! 762: ! 763: conf.cf_port = ! 764: (GETPORT(ports[i]+O_PORTA)<<8) + GETPORT(ports[i]+O_PORTB); ! 765: ! 766: setup[setup_count].irq = IRQ_MIN + conf.cf_irq; ! 767: setup[setup_count].scsiid = conf.cf_id; ! 768: setup[setup_count].reconnect = conf.cf_tardisc; ! 769: setup[setup_count].parity = !conf.cf_parity; ! 770: setup[setup_count].synchronous = 0 /* FIXME: conf.cf_syncneg */; ! 771: setup[setup_count].delay = DELAY_DEFAULT; ! 772: #ifdef DEBUG_AHA152X ! 773: setup[setup_count].debug = DEBUG_DEFAULT; ! 774: #endif ! 775: setup_count++; ! 776: } ! 777: } ! 778: ! 779: printk("auto configuration: ok, "); ! 780: } ! 781: #endif ! 782: ! 783: printk("detection complete\n"); ! 784: ! 785: for(i=0; i<setup_count; i++) ! 786: { ! 787: struct Scsi_Host *shpnt; ! 788: ! 789: shpnt = aha152x_host[setup[i].irq-IRQ_MIN] = ! 790: scsi_register(tpnt, sizeof(struct aha152x_hostdata)); ! 791: ! 792: shpnt->io_port = setup[i].io_port; ! 793: shpnt->n_io_port = IO_RANGE; ! 794: shpnt->irq = setup[i].irq; ! 795: ! 796: ISSUE_SC = (Scsi_Cmnd *) NULL; ! 797: CURRENT_SC = (Scsi_Cmnd *) NULL; ! 798: DISCONNECTED_SC = (Scsi_Cmnd *) NULL; ! 799: ! 800: HOSTDATA(shpnt)->reconnect = setup[i].reconnect; ! 801: HOSTDATA(shpnt)->parity = setup[i].parity; ! 802: HOSTDATA(shpnt)->synchronous = setup[i].synchronous; ! 803: HOSTDATA(shpnt)->delay = setup[i].delay; ! 804: #ifdef DEBUG_AHA152X ! 805: HOSTDATA(shpnt)->debug = setup[i].debug; ! 806: #endif ! 807: ! 808: HOSTDATA(shpnt)->aborting = 0; ! 809: HOSTDATA(shpnt)->abortion_complete = 0; ! 810: HOSTDATA(shpnt)->abort_result = 0; ! 811: HOSTDATA(shpnt)->commands = 0; ! 812: ! 813: HOSTDATA(shpnt)->message_len = 0; ! 814: ! 815: for(j=0; j<8; j++) ! 816: HOSTDATA(shpnt)->syncrate[j] = 0; ! 817: ! 818: SETPORT(SCSIID, setup[i].scsiid << 4); ! 819: shpnt->this_id=setup[i].scsiid; ! 820: ! 821: if(setup[i].reconnect) ! 822: shpnt->hostt->can_queue=AHA152X_MAXQUEUE; ! 823: ! 824: /* RESET OUT */ ! 825: SETBITS(SCSISEQ, SCSIRSTO); ! 826: do_pause(30); ! 827: CLRBITS(SCSISEQ, SCSIRSTO); ! 828: do_pause(setup[i].delay); ! 829: ! 830: aha152x_reset_ports(shpnt); ! 831: ! 832: printk("aha152x%d: vital data: PORTBASE=0x%03x, IRQ=%d, SCSI ID=%d," ! 833: " reconnect=%s, parity=%s, synchronous=%s, delay=%d\n", ! 834: i, ! 835: shpnt->io_port, ! 836: shpnt->irq, ! 837: shpnt->this_id, ! 838: HOSTDATA(shpnt)->reconnect ? "enabled" : "disabled", ! 839: HOSTDATA(shpnt)->parity ? "enabled" : "disabled", ! 840: HOSTDATA(shpnt)->synchronous ? "enabled" : "disabled", ! 841: HOSTDATA(shpnt)->delay); ! 842: ! 843: request_region(shpnt->io_port, IO_RANGE, "aha152x"); /* Register */ ! 844: ! 845: /* not expecting any interrupts */ ! 846: SETPORT(SIMODE0, 0); ! 847: SETPORT(SIMODE1, 0); ! 848: ! 849: SETBITS(DMACNTRL0, INTEN); ! 850: ! 851: ok = request_irq(setup[i].irq, aha152x_intr, SA_INTERRUPT, "aha152x"); ! 852: ! 853: if(ok<0) ! 854: { ! 855: if(ok == -EINVAL) ! 856: { ! 857: printk("aha152x%d: bad IRQ %d.\n", i, setup[i].irq); ! 858: printk(" Contact author.\n"); ! 859: } ! 860: else ! 861: if(ok == -EBUSY) ! 862: printk("aha152x%d: IRQ %d already in use. Configure another.\n", ! 863: i, setup[i].irq); ! 864: else ! 865: { ! 866: printk("\naha152x%d: Unexpected error code on" ! 867: " requesting IRQ %d.\n", i, setup[i].irq); ! 868: printk(" Contact author.\n"); ! 869: } ! 870: printk("aha152x: driver needs an IRQ.\n"); ! 871: continue; ! 872: } ! 873: } ! 874: ! 875: return (setup_count>0); ! 876: } ! 877: ! 878: /* ! 879: * Queue a command and setup interrupts for a free bus. ! 880: */ ! 881: int aha152x_queue(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *)) ! 882: { ! 883: struct Scsi_Host *shpnt = SCpnt->host; ! 884: unsigned long flags; ! 885: ! 886: #if defined(DEBUG_RACE) ! 887: enter_driver("queue"); ! 888: #else ! 889: #if defined(DEBUG_QUEUE) ! 890: if(HOSTDATA(shpnt)->debug & debug_queue) ! 891: printk("aha152x: queue(), "); ! 892: #endif ! 893: #endif ! 894: ! 895: #if defined(DEBUG_QUEUE) ! 896: if(HOSTDATA(shpnt)->debug & debug_queue) ! 897: { ! 898: printk("SCpnt (target = %d lun = %d cmnd = ", ! 899: SCpnt->target, SCpnt->lun); ! 900: print_command(SCpnt->cmnd); ! 901: printk(", cmd_len=%d, pieces = %d size = %u), ", ! 902: SCpnt->cmd_len, SCpnt->use_sg, SCpnt->request_bufflen); ! 903: disp_ports(shpnt); ! 904: } ! 905: #endif ! 906: ! 907: SCpnt->scsi_done = done; ! 908: ! 909: /* setup scratch area ! 910: SCp.ptr : buffer pointer ! 911: SCp.this_residual : buffer length ! 912: SCp.buffer : next buffer ! 913: SCp.buffers_residual : left buffers in list ! 914: SCp.phase : current state of the command */ ! 915: SCpnt->SCp.phase = not_issued; ! 916: if (SCpnt->use_sg) ! 917: { ! 918: SCpnt->SCp.buffer = ! 919: (struct scatterlist *) SCpnt->request_buffer; ! 920: SCpnt->SCp.ptr = SCpnt->SCp.buffer->address; ! 921: SCpnt->SCp.this_residual = SCpnt->SCp.buffer->length; ! 922: SCpnt->SCp.buffers_residual = SCpnt->use_sg - 1; ! 923: } ! 924: else ! 925: { ! 926: SCpnt->SCp.ptr = (char *)SCpnt->request_buffer; ! 927: SCpnt->SCp.this_residual = SCpnt->request_bufflen; ! 928: SCpnt->SCp.buffer = NULL; ! 929: SCpnt->SCp.buffers_residual = 0; ! 930: } ! 931: ! 932: SCpnt->SCp.Status = CHECK_CONDITION; ! 933: SCpnt->SCp.Message = 0; ! 934: SCpnt->SCp.have_data_in = 0; ! 935: SCpnt->SCp.sent_command = 0; ! 936: ! 937: /* Turn led on, when this is the first command. */ ! 938: save_flags(flags); ! 939: cli(); ! 940: HOSTDATA(shpnt)->commands++; ! 941: if(HOSTDATA(shpnt)->commands==1) ! 942: SETPORT(PORTA, 1); ! 943: ! 944: #if defined(DEBUG_QUEUES) ! 945: if(HOSTDATA(shpnt)->debug & debug_queues) ! 946: printk("i+ (%d), ", HOSTDATA(shpnt)->commands); ! 947: #endif ! 948: append_SC(&ISSUE_SC, SCpnt); ! 949: ! 950: /* Enable bus free interrupt, when we aren't currently on the bus */ ! 951: if(!CURRENT_SC) ! 952: { ! 953: SETPORT(SIMODE0, DISCONNECTED_SC ? ENSELDI : 0); ! 954: SETPORT(SIMODE1, ISSUE_SC ? ENBUSFREE : 0); ! 955: } ! 956: restore_flags(flags); ! 957: ! 958: #if defined(DEBUG_RACE) ! 959: leave_driver("queue"); ! 960: #endif ! 961: ! 962: return 0; ! 963: } ! 964: ! 965: /* ! 966: * We only support commands in interrupt-driven fashion ! 967: */ ! 968: int aha152x_command(Scsi_Cmnd *SCpnt) ! 969: { ! 970: printk("aha152x: interrupt driven driver; use aha152x_queue()\n"); ! 971: return -1; ! 972: } ! 973: ! 974: /* ! 975: * Abort a queued command ! 976: * (commands that are on the bus can't be aborted easily) ! 977: */ ! 978: int aha152x_abort(Scsi_Cmnd *SCpnt) ! 979: { ! 980: struct Scsi_Host *shpnt = SCpnt->host; ! 981: unsigned long flags; ! 982: Scsi_Cmnd *ptr, *prev; ! 983: ! 984: save_flags(flags); ! 985: cli(); ! 986: ! 987: #if defined(DEBUG_ABORT) ! 988: if(HOSTDATA(shpnt)->debug & debug_abort) ! 989: { ! 990: printk("aha152x: abort(), SCpnt=0x%08x, ", (unsigned int) SCpnt); ! 991: show_queues(shpnt); ! 992: } ! 993: #endif ! 994: ! 995: /* look for command in issue queue */ ! 996: for(ptr=ISSUE_SC, prev=NULL; ! 997: ptr && ptr!=SCpnt; ! 998: prev=ptr, ptr=(Scsi_Cmnd *) ptr->host_scribble) ! 999: ; ! 1000: ! 1001: if(ptr) ! 1002: { ! 1003: /* dequeue */ ! 1004: if(prev) ! 1005: prev->host_scribble = ptr->host_scribble; ! 1006: else ! 1007: ISSUE_SC = (Scsi_Cmnd *) ptr->host_scribble; ! 1008: restore_flags(flags); ! 1009: ! 1010: ptr->host_scribble = NULL; ! 1011: ptr->result = DID_ABORT << 16; ! 1012: ptr->scsi_done(ptr); ! 1013: return SCSI_ABORT_SUCCESS; ! 1014: } ! 1015: ! 1016: /* if the bus is busy or a command is currently processed, ! 1017: we can't do anything more */ ! 1018: if (TESTLO(SSTAT1, BUSFREE) || (CURRENT_SC && CURRENT_SC!=SCpnt)) ! 1019: { ! 1020: /* fail abortion, if bus is busy */ ! 1021: ! 1022: if(!CURRENT_SC) ! 1023: printk("bus busy w/o current command, "); ! 1024: ! 1025: restore_flags(flags); ! 1026: return SCSI_ABORT_BUSY; ! 1027: } ! 1028: ! 1029: /* bus is free */ ! 1030: ! 1031: if(CURRENT_SC) ! 1032: { ! 1033: /* target entered bus free before COMMAND COMPLETE, nothing to abort */ ! 1034: restore_flags(flags); ! 1035: CURRENT_SC->result = DID_ERROR << 16; ! 1036: CURRENT_SC->scsi_done(CURRENT_SC); ! 1037: CURRENT_SC = (Scsi_Cmnd *) NULL; ! 1038: return SCSI_ABORT_SUCCESS; ! 1039: } ! 1040: ! 1041: /* look for command in disconnected queue */ ! 1042: for(ptr=DISCONNECTED_SC, prev=NULL; ! 1043: ptr && ptr!=SCpnt; ! 1044: prev=ptr, ptr=(Scsi_Cmnd *) ptr->host_scribble) ! 1045: ; ! 1046: ! 1047: if(ptr) ! 1048: if(!HOSTDATA(shpnt)->aborting) ! 1049: { ! 1050: /* dequeue */ ! 1051: if(prev) ! 1052: prev->host_scribble = ptr->host_scribble; ! 1053: else ! 1054: DISCONNECTED_SC = (Scsi_Cmnd *) ptr->host_scribble; ! 1055: ! 1056: /* set command current and initiate selection, ! 1057: let the interrupt routine take care of the abortion */ ! 1058: CURRENT_SC = ptr; ! 1059: ptr->SCp.phase = in_selection|aborted; ! 1060: SETPORT(SCSIID, (shpnt->this_id << OID_) | CURRENT_SC->target); ! 1061: ! 1062: ADDMSG(ABORT); ! 1063: ! 1064: /* enable interrupts for SELECTION OUT DONE and SELECTION TIME OUT */ ! 1065: SETPORT(SIMODE0, ENSELDO | (DISCONNECTED_SC ? ENSELDI : 0)); ! 1066: SETPORT(SIMODE1, ENSELTIMO); ! 1067: ! 1068: /* Enable SELECTION OUT sequence */ ! 1069: SETBITS(SCSISEQ, ENSELO | ENAUTOATNO); ! 1070: ! 1071: SETBITS(DMACNTRL0, INTEN); ! 1072: HOSTDATA(shpnt)->abort_result=SCSI_ABORT_SUCCESS; ! 1073: HOSTDATA(shpnt)->aborting++; ! 1074: HOSTDATA(shpnt)->abortion_complete=0; ! 1075: ! 1076: sti(); /* Hi Eric, guess what ;-) */ ! 1077: ! 1078: /* sleep until the abortion is complete */ ! 1079: while(!HOSTDATA(shpnt)->abortion_complete) ! 1080: barrier(); ! 1081: HOSTDATA(shpnt)->aborting=0; ! 1082: return HOSTDATA(shpnt)->abort_result; ! 1083: } ! 1084: else ! 1085: { ! 1086: /* we're already aborting a command */ ! 1087: restore_flags(flags); ! 1088: return SCSI_ABORT_BUSY; ! 1089: } ! 1090: ! 1091: /* command wasn't found */ ! 1092: printk("command not found\n"); ! 1093: restore_flags(flags); ! 1094: return SCSI_ABORT_NOT_RUNNING; ! 1095: } ! 1096: ! 1097: /* ! 1098: * Restore default values to the AIC-6260 registers and reset the fifos ! 1099: */ ! 1100: static void aha152x_reset_ports(struct Scsi_Host *shpnt) ! 1101: { ! 1102: /* disable interrupts */ ! 1103: SETPORT(DMACNTRL0, RSTFIFO); ! 1104: ! 1105: SETPORT(SCSISEQ, 0); ! 1106: ! 1107: SETPORT(SXFRCTL1, 0); ! 1108: SETPORT(SCSISIG, 0); ! 1109: SETPORT(SCSIRATE, 0); ! 1110: ! 1111: /* clear all interrupt conditions */ ! 1112: SETPORT(SSTAT0, 0x7f); ! 1113: SETPORT(SSTAT1, 0xef); ! 1114: ! 1115: SETPORT(SSTAT4, SYNCERR|FWERR|FRERR); ! 1116: ! 1117: SETPORT(DMACNTRL0, 0); ! 1118: SETPORT(DMACNTRL1, 0); ! 1119: ! 1120: SETPORT(BRSTCNTRL, 0xf1); ! 1121: ! 1122: /* clear SCSI fifo and transfer count */ ! 1123: SETPORT(SXFRCTL0, CH1|CLRCH1|CLRSTCNT); ! 1124: SETPORT(SXFRCTL0, CH1); ! 1125: ! 1126: /* enable interrupts */ ! 1127: SETPORT(SIMODE0, DISCONNECTED_SC ? ENSELDI : 0); ! 1128: SETPORT(SIMODE1, ISSUE_SC ? ENBUSFREE : 0); ! 1129: } ! 1130: ! 1131: /* ! 1132: * Reset registers, reset a hanging bus and ! 1133: * kill active and disconnected commands for target w/o soft reset ! 1134: */ ! 1135: int aha152x_reset(Scsi_Cmnd *SCpnt) ! 1136: { ! 1137: struct Scsi_Host *shpnt = SCpnt->host; ! 1138: unsigned long flags; ! 1139: Scsi_Cmnd *ptr, *prev, *next; ! 1140: ! 1141: aha152x_reset_ports(shpnt); ! 1142: ! 1143: /* Reset, if bus hangs */ ! 1144: if(TESTLO(SSTAT1, BUSFREE)) ! 1145: { ! 1146: CLRBITS(DMACNTRL0, INTEN); ! 1147: ! 1148: #if defined(DEBUG_RESET) ! 1149: if(HOSTDATA(shpnt)->debug & debug_reset) ! 1150: { ! 1151: printk("aha152x: reset(), bus not free: SCSI RESET OUT\n"); ! 1152: show_queues(shpnt); ! 1153: } ! 1154: #endif ! 1155: ! 1156: ptr=CURRENT_SC; ! 1157: if(ptr && !ptr->device->soft_reset) ! 1158: { ! 1159: ptr->host_scribble = NULL; ! 1160: ptr->result = DID_RESET << 16; ! 1161: ptr->scsi_done(CURRENT_SC); ! 1162: CURRENT_SC=NULL; ! 1163: } ! 1164: ! 1165: save_flags(flags); ! 1166: cli(); ! 1167: prev=NULL; ptr=DISCONNECTED_SC; ! 1168: while(ptr) ! 1169: { ! 1170: if(!ptr->device->soft_reset) ! 1171: { ! 1172: if(prev) ! 1173: prev->host_scribble = ptr->host_scribble; ! 1174: else ! 1175: DISCONNECTED_SC = (Scsi_Cmnd *) ptr->host_scribble; ! 1176: ! 1177: next = (Scsi_Cmnd *) ptr->host_scribble; ! 1178: ! 1179: ptr->host_scribble = NULL; ! 1180: ptr->result = DID_RESET << 16; ! 1181: ptr->scsi_done(ptr); ! 1182: ! 1183: ptr = next; ! 1184: } ! 1185: else ! 1186: { ! 1187: prev=ptr; ! 1188: ptr = (Scsi_Cmnd *) ptr->host_scribble; ! 1189: } ! 1190: } ! 1191: restore_flags(flags); ! 1192: ! 1193: #if defined(DEBUG_RESET) ! 1194: if(HOSTDATA(shpnt)->debug & debug_reset) ! 1195: { ! 1196: printk("commands on targets w/ soft-resets:\n"); ! 1197: show_queues(shpnt); ! 1198: } ! 1199: #endif ! 1200: ! 1201: /* RESET OUT */ ! 1202: SETPORT(SCSISEQ, SCSIRSTO); ! 1203: do_pause(30); ! 1204: SETPORT(SCSISEQ, 0); ! 1205: do_pause(DELAY); ! 1206: ! 1207: SETPORT(SIMODE0, DISCONNECTED_SC ? ENSELDI : 0); ! 1208: SETPORT(SIMODE1, ISSUE_SC ? ENBUSFREE : 0); ! 1209: ! 1210: SETPORT(DMACNTRL0, INTEN); ! 1211: } ! 1212: ! 1213: return SCSI_RESET_SUCCESS; ! 1214: } ! 1215: ! 1216: /* ! 1217: * Return the "logical geometry" ! 1218: */ ! 1219: int aha152x_biosparam(Scsi_Disk * disk, kdev_t dev, int *info_array) ! 1220: { ! 1221: int size = disk->capacity; ! 1222: ! 1223: #if defined(DEBUG_BIOSPARAM) ! 1224: if(HOSTDATA(shpnt)->debug & debug_biosparam) ! 1225: printk("aha152x_biosparam: dev=%s, size=%d, ", kdevname(dev), size); ! 1226: #endif ! 1227: ! 1228: /* I took this from other SCSI drivers, since it provides ! 1229: the correct data for my devices. */ ! 1230: info_array[0]=64; ! 1231: info_array[1]=32; ! 1232: info_array[2]=size>>11; ! 1233: ! 1234: #if defined(DEBUG_BIOSPARAM) ! 1235: if(HOSTDATA(shpnt)->debug & debug_biosparam) ! 1236: { ! 1237: printk("bios geometry: head=%d, sec=%d, cyl=%d\n", ! 1238: info_array[0], info_array[1], info_array[2]); ! 1239: printk("WARNING: check, if the bios geometry is correct.\n"); ! 1240: } ! 1241: #endif ! 1242: ! 1243: return 0; ! 1244: } ! 1245: ! 1246: /* ! 1247: * Internal done function ! 1248: */ ! 1249: void aha152x_done(struct Scsi_Host *shpnt, int error) ! 1250: { ! 1251: unsigned long flags; ! 1252: Scsi_Cmnd *done_SC; ! 1253: ! 1254: #if defined(DEBUG_DONE) ! 1255: if(HOSTDATA(shpnt)->debug & debug_done) ! 1256: { ! 1257: printk("\naha152x: done(), "); ! 1258: disp_ports(shpnt); ! 1259: } ! 1260: #endif ! 1261: ! 1262: if (CURRENT_SC) ! 1263: { ! 1264: #if defined(DEBUG_DONE) ! 1265: if(HOSTDATA(shpnt)->debug & debug_done) ! 1266: printk("done(%x), ", error); ! 1267: #endif ! 1268: ! 1269: save_flags(flags); ! 1270: cli(); ! 1271: ! 1272: done_SC = CURRENT_SC; ! 1273: CURRENT_SC = NULL; ! 1274: ! 1275: /* turn led off, when no commands are in the driver */ ! 1276: HOSTDATA(shpnt)->commands--; ! 1277: if(!HOSTDATA(shpnt)->commands) ! 1278: SETPORT(PORTA, 0); /* turn led off */ ! 1279: ! 1280: #if defined(DEBUG_QUEUES) ! 1281: if(HOSTDATA(shpnt)->debug & debug_queues) ! 1282: printk("ok (%d), ", HOSTDATA(shpnt)->commands); ! 1283: #endif ! 1284: restore_flags(flags); ! 1285: ! 1286: SETPORT(SIMODE0, DISCONNECTED_SC ? ENSELDI : 0); ! 1287: SETPORT(SIMODE1, ISSUE_SC ? ENBUSFREE : 0); ! 1288: ! 1289: #if defined(DEBUG_PHASES) ! 1290: if(HOSTDATA(shpnt)->debug & debug_phases) ! 1291: printk("BUS FREE loop, "); ! 1292: #endif ! 1293: while(TESTLO(SSTAT1, BUSFREE)) ! 1294: barrier(); ! 1295: #if defined(DEBUG_PHASES) ! 1296: if(HOSTDATA(shpnt)->debug & debug_phases) ! 1297: printk("BUS FREE\n"); ! 1298: #endif ! 1299: ! 1300: done_SC->result = error; ! 1301: if(done_SC->scsi_done) ! 1302: { ! 1303: #if defined(DEBUG_DONE) ! 1304: if(HOSTDATA(shpnt)->debug & debug_done) ! 1305: printk("calling scsi_done, "); ! 1306: #endif ! 1307: done_SC->scsi_done(done_SC); ! 1308: #if defined(DEBUG_DONE) ! 1309: if(HOSTDATA(shpnt)->debug & debug_done) ! 1310: printk("done returned, "); ! 1311: #endif ! 1312: } ! 1313: else ! 1314: panic("aha152x: current_SC->scsi_done() == NULL"); ! 1315: } ! 1316: else ! 1317: aha152x_panic(shpnt, "done() called outside of command"); ! 1318: } ! 1319: ! 1320: /* ! 1321: * Interrupts handler (main routine of the driver) ! 1322: */ ! 1323: void aha152x_intr(int irqno, struct pt_regs * regs) ! 1324: { ! 1325: struct Scsi_Host *shpnt = aha152x_host[irqno-IRQ_MIN]; ! 1326: unsigned int flags; ! 1327: int done=0, phase; ! 1328: ! 1329: #if defined(DEBUG_RACE) ! 1330: enter_driver("intr"); ! 1331: #else ! 1332: #if defined(DEBUG_INTR) ! 1333: if(HOSTDATA(shpnt)->debug & debug_intr) ! 1334: printk("\naha152x: intr(), "); ! 1335: #endif ! 1336: #endif ! 1337: ! 1338: /* no more interrupts from the controller, while we busy. ! 1339: INTEN has to be restored, when we're ready to leave ! 1340: intr(). To avoid race conditions we have to return ! 1341: immediately afterwards. */ ! 1342: CLRBITS(DMACNTRL0, INTEN); ! 1343: sti(); /* Yes, sti() really needs to be here */ ! 1344: ! 1345: /* disconnected target is trying to reconnect. ! 1346: Only possible, if we have disconnected nexuses and ! 1347: nothing is occupying the bus. ! 1348: */ ! 1349: if(TESTHI(SSTAT0, SELDI) && ! 1350: DISCONNECTED_SC && ! 1351: (!CURRENT_SC || (CURRENT_SC->SCp.phase & in_selection)) ) ! 1352: { ! 1353: int identify_msg, target, i; ! 1354: ! 1355: /* Avoid conflicts when a target reconnects ! 1356: while we are trying to connect to another. */ ! 1357: if(CURRENT_SC) ! 1358: { ! 1359: #if defined(DEBUG_QUEUES) ! 1360: if(HOSTDATA(shpnt)->debug & debug_queues) ! 1361: printk("i+, "); ! 1362: #endif ! 1363: save_flags(flags); ! 1364: cli(); ! 1365: append_SC(&ISSUE_SC, CURRENT_SC); ! 1366: CURRENT_SC=NULL; ! 1367: restore_flags(flags); ! 1368: } ! 1369: ! 1370: /* disable sequences */ ! 1371: SETPORT(SCSISEQ, 0); ! 1372: SETPORT(SSTAT0, CLRSELDI); ! 1373: SETPORT(SSTAT1, CLRBUSFREE); ! 1374: ! 1375: #if defined(DEBUG_QUEUES) || defined(DEBUG_PHASES) ! 1376: if(HOSTDATA(shpnt)->debug & (debug_queues|debug_phases)) ! 1377: printk("reselected, "); ! 1378: #endif ! 1379: ! 1380: i = GETPORT(SELID) & ~(1 << shpnt->this_id); ! 1381: target=0; ! 1382: if(i) ! 1383: for(; (i & 1)==0; target++, i>>=1) ! 1384: ; ! 1385: else ! 1386: aha152x_panic(shpnt, "reconnecting target unknown"); ! 1387: ! 1388: #if defined(DEBUG_QUEUES) ! 1389: if(HOSTDATA(shpnt)->debug & debug_queues) ! 1390: printk("SELID=%02x, target=%d, ", GETPORT(SELID), target); ! 1391: #endif ! 1392: SETPORT(SCSIID, (shpnt->this_id << OID_) | target); ! 1393: SETPORT(SCSISEQ, ENRESELI); ! 1394: ! 1395: if(TESTLO(SSTAT0, SELDI)) ! 1396: aha152x_panic(shpnt, "RESELI failed"); ! 1397: ! 1398: SETPORT(SCSIRATE, HOSTDATA(shpnt)->syncrate[target]&0x7f); ! 1399: ! 1400: SETPORT(SCSISIG, P_MSGI); ! 1401: ! 1402: /* Get identify message */ ! 1403: if((i=getphase(shpnt))!=P_MSGI) ! 1404: { ! 1405: printk("target doesn't enter MSGI to identify (phase=%02x)\n", i); ! 1406: aha152x_panic(shpnt, "unknown lun"); ! 1407: } ! 1408: SETPORT(SCSISEQ, 0); ! 1409: ! 1410: SETPORT(SXFRCTL0, CH1); ! 1411: ! 1412: identify_msg = GETPORT(SCSIBUS); ! 1413: ! 1414: if(!(identify_msg & IDENTIFY_BASE)) ! 1415: { ! 1416: printk("target=%d, inbound message (%02x) != IDENTIFY\n", ! 1417: target, identify_msg); ! 1418: aha152x_panic(shpnt, "unknown lun"); ! 1419: } ! 1420: ! 1421: ! 1422: #if defined(DEBUG_QUEUES) ! 1423: if(HOSTDATA(shpnt)->debug & debug_queues) ! 1424: printk("identify=%02x, lun=%d, ", identify_msg, identify_msg & 0x3f); ! 1425: #endif ! 1426: ! 1427: save_flags(flags); ! 1428: cli(); ! 1429: ! 1430: #if defined(DEBUG_QUEUES) ! 1431: if(HOSTDATA(shpnt)->debug & debug_queues) ! 1432: printk("d-, "); ! 1433: #endif ! 1434: CURRENT_SC = remove_SC(&DISCONNECTED_SC, ! 1435: target, ! 1436: identify_msg & 0x3f); ! 1437: ! 1438: if(!CURRENT_SC) ! 1439: { ! 1440: printk("lun=%d, ", identify_msg & 0x3f); ! 1441: aha152x_panic(shpnt, "no disconnected command for that lun"); ! 1442: } ! 1443: ! 1444: CURRENT_SC->SCp.phase &= ~disconnected; ! 1445: restore_flags(flags); ! 1446: ! 1447: make_acklow(shpnt); ! 1448: if(getphase(shpnt)!=P_MSGI) { ! 1449: SETPORT(SIMODE0, 0); ! 1450: SETPORT(SIMODE1, ENPHASEMIS|ENBUSFREE); ! 1451: #if defined(DEBUG_RACE) ! 1452: leave_driver("(reselected) intr"); ! 1453: #endif ! 1454: SETBITS(DMACNTRL0, INTEN); ! 1455: return; ! 1456: } ! 1457: } ! 1458: ! 1459: /* Check, if we aren't busy with a command */ ! 1460: if(!CURRENT_SC) ! 1461: { ! 1462: /* bus is free to issue a queued command */ ! 1463: if(TESTHI(SSTAT1, BUSFREE) && ISSUE_SC) ! 1464: { ! 1465: save_flags(flags); ! 1466: cli(); ! 1467: #if defined(DEBUG_QUEUES) ! 1468: if(HOSTDATA(shpnt)->debug & debug_queues) ! 1469: printk("i-, "); ! 1470: #endif ! 1471: CURRENT_SC = remove_first_SC(&ISSUE_SC); ! 1472: restore_flags(flags); ! 1473: ! 1474: #if defined(DEBUG_INTR) || defined(DEBUG_SELECTION) || defined(DEBUG_PHASES) ! 1475: if(HOSTDATA(shpnt)->debug & (debug_intr|debug_selection|debug_phases)) ! 1476: printk("issuing command, "); ! 1477: #endif ! 1478: CURRENT_SC->SCp.phase = in_selection; ! 1479: ! 1480: #if defined(DEBUG_INTR) || defined(DEBUG_SELECTION) || defined(DEBUG_PHASES) ! 1481: if(HOSTDATA(shpnt)->debug & (debug_intr|debug_selection|debug_phases)) ! 1482: printk("selecting %d, ", CURRENT_SC->target); ! 1483: #endif ! 1484: SETPORT(SCSIID, (shpnt->this_id << OID_) | CURRENT_SC->target); ! 1485: ! 1486: /* Enable interrupts for SELECTION OUT DONE and SELECTION OUT INITIATED */ ! 1487: SETPORT(SXFRCTL1, HOSTDATA(shpnt)->parity ? (ENSPCHK|ENSTIMER) : ENSTIMER); ! 1488: ! 1489: /* enable interrupts for SELECTION OUT DONE and SELECTION TIME OUT */ ! 1490: SETPORT(SIMODE0, ENSELDO | (DISCONNECTED_SC ? ENSELDI : 0)); ! 1491: SETPORT(SIMODE1, ENSELTIMO); ! 1492: ! 1493: /* Enable SELECTION OUT sequence */ ! 1494: SETBITS(SCSISEQ, ENSELO | ENAUTOATNO); ! 1495: ! 1496: } ! 1497: else ! 1498: { ! 1499: /* No command we are busy with and no new to issue */ ! 1500: printk("aha152x: ignoring spurious interrupt, nothing to do\n"); ! 1501: if(TESTHI(DMACNTRL0, SWINT)) { ! 1502: printk("aha152x: SWINT is set! Why?\n"); ! 1503: CLRBITS(DMACNTRL0, SWINT); ! 1504: } ! 1505: show_queues(shpnt); ! 1506: } ! 1507: ! 1508: #if defined(DEBUG_RACE) ! 1509: leave_driver("(selecting) intr"); ! 1510: #endif ! 1511: SETBITS(DMACNTRL0, INTEN); ! 1512: return; ! 1513: } ! 1514: ! 1515: /* the bus is busy with something */ ! 1516: ! 1517: #if defined(DEBUG_INTR) ! 1518: if(HOSTDATA(shpnt)->debug & debug_intr) ! 1519: disp_ports(shpnt); ! 1520: #endif ! 1521: ! 1522: /* we are waiting for the result of a selection attempt */ ! 1523: if(CURRENT_SC->SCp.phase & in_selection) ! 1524: { ! 1525: if(TESTLO(SSTAT1, SELTO)) ! 1526: /* no timeout */ ! 1527: if(TESTHI(SSTAT0, SELDO)) ! 1528: { ! 1529: /* clear BUS FREE interrupt */ ! 1530: SETPORT(SSTAT1, CLRBUSFREE); ! 1531: ! 1532: /* Disable SELECTION OUT sequence */ ! 1533: CLRBITS(SCSISEQ, ENSELO|ENAUTOATNO); ! 1534: ! 1535: /* Disable SELECTION OUT DONE interrupt */ ! 1536: CLRBITS(SIMODE0, ENSELDO); ! 1537: CLRBITS(SIMODE1, ENSELTIMO); ! 1538: ! 1539: if(TESTLO(SSTAT0, SELDO)) ! 1540: { ! 1541: printk("aha152x: passing bus free condition\n"); ! 1542: ! 1543: #if defined(DEBUG_RACE) ! 1544: leave_driver("(passing bus free) intr"); ! 1545: #endif ! 1546: SETBITS(DMACNTRL0, INTEN); ! 1547: ! 1548: if(CURRENT_SC->SCp.phase & aborted) ! 1549: { ! 1550: HOSTDATA(shpnt)->abort_result=SCSI_ABORT_ERROR; ! 1551: HOSTDATA(shpnt)->abortion_complete++; ! 1552: } ! 1553: ! 1554: aha152x_done(shpnt, DID_NO_CONNECT << 16); ! 1555: return; ! 1556: } ! 1557: #if defined(DEBUG_SELECTION) || defined(DEBUG_PHASES) ! 1558: if(HOSTDATA(shpnt)->debug & (debug_selection|debug_phases)) ! 1559: printk("SELDO (SELID=%x), ", GETPORT(SELID)); ! 1560: #endif ! 1561: ! 1562: /* selection was done */ ! 1563: SETPORT(SSTAT0, CLRSELDO); ! 1564: ! 1565: #if defined(DEBUG_ABORT) ! 1566: if((HOSTDATA(shpnt)->debug & debug_abort) && (CURRENT_SC->SCp.phase & aborted)) ! 1567: printk("(ABORT) target selected, "); ! 1568: #endif ! 1569: ! 1570: CURRENT_SC->SCp.phase &= ~in_selection; ! 1571: CURRENT_SC->SCp.phase |= in_other; ! 1572: ! 1573: ADDMSG(IDENTIFY(HOSTDATA(shpnt)->reconnect,CURRENT_SC->lun)); ! 1574: ! 1575: if(!(SYNCRATE&0x80) && HOSTDATA(shpnt)->synchronous) ! 1576: { ! 1577: ADDMSG(EXTENDED_MESSAGE); ! 1578: ADDMSG(3); ! 1579: ADDMSG(EXTENDED_SDTR); ! 1580: ADDMSG(50); ! 1581: ADDMSG(8); ! 1582: ! 1583: printk("outbound SDTR: "); ! 1584: print_msg(&MSG(MSGLEN-5)); ! 1585: ! 1586: SYNCRATE=0x80; ! 1587: CURRENT_SC->SCp.phase |= in_sync; ! 1588: } ! 1589: ! 1590: #if defined(DEBUG_RACE) ! 1591: leave_driver("(SELDO) intr"); ! 1592: #endif ! 1593: SETPORT(SCSIRATE, SYNCRATE&0x7f); ! 1594: ! 1595: SETPORT(SCSISIG, P_MSGO); ! 1596: ! 1597: SETPORT(SIMODE0, 0); ! 1598: SETPORT(SIMODE1, ENREQINIT|ENBUSFREE); ! 1599: SETBITS(DMACNTRL0, INTEN); ! 1600: return; ! 1601: } ! 1602: else ! 1603: aha152x_panic(shpnt, "neither timeout nor selection\007"); ! 1604: else ! 1605: { ! 1606: #if defined(DEBUG_SELECTION) || defined(DEBUG_PHASES) ! 1607: if(HOSTDATA(shpnt)->debug & (debug_selection|debug_phases)) ! 1608: printk("SELTO, "); ! 1609: #endif ! 1610: /* end selection attempt */ ! 1611: CLRBITS(SCSISEQ, ENSELO|ENAUTOATNO); ! 1612: ! 1613: /* timeout */ ! 1614: SETPORT(SSTAT1, CLRSELTIMO); ! 1615: ! 1616: SETPORT(SIMODE0, DISCONNECTED_SC ? ENSELDI : 0); ! 1617: SETPORT(SIMODE1, ISSUE_SC ? ENBUSFREE : 0); ! 1618: SETBITS(DMACNTRL0, INTEN); ! 1619: #if defined(DEBUG_RACE) ! 1620: leave_driver("(SELTO) intr"); ! 1621: #endif ! 1622: ! 1623: if(CURRENT_SC->SCp.phase & aborted) ! 1624: { ! 1625: #if defined(DEBUG_ABORT) ! 1626: if(HOSTDATA(shpnt)->debug & debug_abort) ! 1627: printk("(ABORT) selection timeout, "); ! 1628: #endif ! 1629: HOSTDATA(shpnt)->abort_result=SCSI_ABORT_ERROR; ! 1630: HOSTDATA(shpnt)->abortion_complete++; ! 1631: } ! 1632: ! 1633: if(TESTLO(SSTAT0, SELINGO)) ! 1634: /* ARBITRATION not won */ ! 1635: aha152x_done(shpnt, DID_BUS_BUSY << 16); ! 1636: else ! 1637: /* ARBITRATION won, but SELECTION failed */ ! 1638: aha152x_done(shpnt, DID_NO_CONNECT << 16); ! 1639: ! 1640: return; ! 1641: } ! 1642: } ! 1643: ! 1644: /* enable interrupt, when target leaves current phase */ ! 1645: phase = getphase(shpnt); ! 1646: if(!(phase & ~P_MASK)) /* "real" phase */ ! 1647: SETPORT(SCSISIG, phase); ! 1648: SETPORT(SSTAT1, CLRPHASECHG); ! 1649: CURRENT_SC->SCp.phase = ! 1650: (CURRENT_SC->SCp.phase & ~((P_MASK|1)<<16)) | (phase << 16); ! 1651: ! 1652: /* information transfer phase */ ! 1653: switch(phase) ! 1654: { ! 1655: case P_MSGO: /* MESSAGE OUT */ ! 1656: { ! 1657: int i, identify=0, abort=0; ! 1658: ! 1659: #if defined(DEBUG_INTR) || defined(DEBUG_MSGO) || defined(DEBUG_PHASES) ! 1660: if(HOSTDATA(shpnt)->debug & (debug_intr|debug_msgo|debug_phases)) ! 1661: printk("MESSAGE OUT, "); ! 1662: #endif ! 1663: if(MSGLEN==0) ! 1664: { ! 1665: ADDMSG(MESSAGE_REJECT); ! 1666: #if defined(DEBUG_MSGO) ! 1667: if(HOSTDATA(shpnt)->debug & debug_msgo) ! 1668: printk("unexpected MSGO; rejecting, "); ! 1669: #endif ! 1670: } ! 1671: ! 1672: ! 1673: CLRBITS(SXFRCTL0, ENDMA); ! 1674: ! 1675: SETPORT(SIMODE0, 0); ! 1676: SETPORT(SIMODE1, ENPHASEMIS|ENREQINIT|ENBUSFREE); ! 1677: ! 1678: /* wait for data latch to become ready or a phase change */ ! 1679: while(TESTLO(DMASTAT, INTSTAT)) ! 1680: barrier(); ! 1681: ! 1682: #if defined(DEBUG_MSGO) ! 1683: if(HOSTDATA(shpnt)->debug & debug_msgo) ! 1684: { ! 1685: int i; ! 1686: ! 1687: printk("messages ("); ! 1688: for(i=0; i<MSGLEN; i+=print_msg(&MSG(i)), printk(" ")) ! 1689: ; ! 1690: printk("), "); ! 1691: } ! 1692: #endif ! 1693: ! 1694: for(i=0; i<MSGLEN && TESTLO(SSTAT1, PHASEMIS); i++) ! 1695: { ! 1696: #if defined(DEBUG_MSGO) ! 1697: if(HOSTDATA(shpnt)->debug & debug_msgo) ! 1698: printk("%x ", MSG(i)); ! 1699: #endif ! 1700: if(i==MSGLEN-1) ! 1701: { ! 1702: /* Leave MESSAGE OUT after transfer */ ! 1703: SETPORT(SSTAT1, CLRATNO); ! 1704: } ! 1705: ! 1706: SETPORT(SCSIDAT, MSG(i)); ! 1707: ! 1708: make_acklow(shpnt); ! 1709: getphase(shpnt); ! 1710: ! 1711: if(MSG(i)==IDENTIFY(HOSTDATA(shpnt)->reconnect,CURRENT_SC->lun)) ! 1712: identify++; ! 1713: ! 1714: if(MSG(i)==ABORT) ! 1715: abort++; ! 1716: ! 1717: } ! 1718: ! 1719: MSGLEN=0; ! 1720: ! 1721: if(identify) ! 1722: CURRENT_SC->SCp.phase |= sent_ident; ! 1723: ! 1724: if(abort) ! 1725: { ! 1726: /* revive abort(); abort() enables interrupts */ ! 1727: HOSTDATA(shpnt)->abort_result=SCSI_ABORT_SUCCESS; ! 1728: HOSTDATA(shpnt)->abortion_complete++; ! 1729: ! 1730: CURRENT_SC->SCp.phase &= ~(P_MASK<<16); ! 1731: ! 1732: /* exit */ ! 1733: SETBITS(DMACNTRL0, INTEN); ! 1734: #if defined(DEBUG_RACE) ! 1735: leave_driver("(ABORT) intr"); ! 1736: #endif ! 1737: aha152x_done(shpnt, DID_ABORT<<16); ! 1738: return; ! 1739: } ! 1740: } ! 1741: break; ! 1742: ! 1743: case P_CMD: /* COMMAND phase */ ! 1744: #if defined(DEBUG_INTR) || defined(DEBUG_CMD) || defined(DEBUG_PHASES) ! 1745: if(HOSTDATA(shpnt)->debug & (debug_intr|debug_cmd|debug_phases)) ! 1746: printk("COMMAND, "); ! 1747: #endif ! 1748: if(!(CURRENT_SC->SCp.sent_command)) ! 1749: { ! 1750: int i; ! 1751: ! 1752: CLRBITS(SXFRCTL0, ENDMA); ! 1753: ! 1754: SETPORT(SIMODE0, 0); ! 1755: SETPORT(SIMODE1, ENPHASEMIS|ENREQINIT|ENBUSFREE); ! 1756: ! 1757: /* wait for data latch to become ready or a phase change */ ! 1758: while(TESTLO(DMASTAT, INTSTAT)) ! 1759: barrier(); ! 1760: ! 1761: for(i=0; i<CURRENT_SC->cmd_len && TESTLO(SSTAT1, PHASEMIS); i++) ! 1762: { ! 1763: SETPORT(SCSIDAT, CURRENT_SC->cmnd[i]); ! 1764: ! 1765: make_acklow(shpnt); ! 1766: getphase(shpnt); ! 1767: } ! 1768: ! 1769: if(i<CURRENT_SC->cmd_len && TESTHI(SSTAT1, PHASEMIS)) ! 1770: aha152x_panic(shpnt, "target left COMMAND"); ! 1771: ! 1772: CURRENT_SC->SCp.sent_command++; ! 1773: } ! 1774: else ! 1775: aha152x_panic(shpnt, "Nothing to send while in COMMAND"); ! 1776: break; ! 1777: ! 1778: case P_MSGI: /* MESSAGE IN phase */ ! 1779: { ! 1780: int start_sync=0; ! 1781: ! 1782: #if defined(DEBUG_INTR) || defined(DEBUG_MSGI) || defined(DEBUG_PHASES) ! 1783: if(HOSTDATA(shpnt)->debug & (debug_intr|debug_msgi|debug_phases)) ! 1784: printk("MESSAGE IN, "); ! 1785: #endif ! 1786: SETPORT(SXFRCTL0, CH1); ! 1787: ! 1788: SETPORT(SIMODE0, 0); ! 1789: SETPORT(SIMODE1, ENBUSFREE); ! 1790: ! 1791: while(phase == P_MSGI) ! 1792: { ! 1793: CURRENT_SC->SCp.Message = GETPORT(SCSIDAT); ! 1794: switch(CURRENT_SC->SCp.Message) ! 1795: { ! 1796: case DISCONNECT: ! 1797: #if defined(DEBUG_MSGI) || defined(DEBUG_PHASES) ! 1798: if(HOSTDATA(shpnt)->debug & (debug_msgi|debug_phases)) ! 1799: printk("target disconnected, "); ! 1800: #endif ! 1801: CURRENT_SC->SCp.Message = 0; ! 1802: CURRENT_SC->SCp.phase |= disconnected; ! 1803: if(!HOSTDATA(shpnt)->reconnect) ! 1804: aha152x_panic(shpnt, "target was not allowed to disconnect"); ! 1805: break; ! 1806: ! 1807: case COMMAND_COMPLETE: ! 1808: #if defined(DEBUG_MSGI) || defined(DEBUG_PHASES) ! 1809: if(HOSTDATA(shpnt)->debug & (debug_msgi|debug_phases)) ! 1810: printk("inbound message (COMMAND COMPLETE), "); ! 1811: #endif ! 1812: done++; ! 1813: break; ! 1814: ! 1815: case MESSAGE_REJECT: ! 1816: if(CURRENT_SC->SCp.phase & in_sync) ! 1817: { ! 1818: CURRENT_SC->SCp.phase &= ~in_sync; ! 1819: SYNCRATE=0x80; ! 1820: printk("synchronous rejected, "); ! 1821: } ! 1822: else ! 1823: printk("inbound message (MESSAGE REJECT), "); ! 1824: #if defined(DEBUG_MSGI) ! 1825: if(HOSTDATA(shpnt)->debug & debug_msgi) ! 1826: printk("inbound message (MESSAGE REJECT), "); ! 1827: #endif ! 1828: break; ! 1829: ! 1830: case SAVE_POINTERS: ! 1831: #if defined(DEBUG_MSGI) ! 1832: if(HOSTDATA(shpnt)->debug & debug_msgi) ! 1833: printk("inbound message (SAVE DATA POINTERS), "); ! 1834: #endif ! 1835: break; ! 1836: ! 1837: case EXTENDED_MESSAGE: ! 1838: { ! 1839: char buffer[16]; ! 1840: int i; ! 1841: ! 1842: #if defined(DEBUG_MSGI) ! 1843: if(HOSTDATA(shpnt)->debug & debug_msgi) ! 1844: printk("inbound message (EXTENDED MESSAGE), "); ! 1845: #endif ! 1846: make_acklow(shpnt); ! 1847: if(getphase(shpnt)!=P_MSGI) ! 1848: break; ! 1849: ! 1850: buffer[0]=EXTENDED_MESSAGE; ! 1851: buffer[1]=GETPORT(SCSIDAT); ! 1852: ! 1853: for(i=0; i<buffer[1] && ! 1854: (make_acklow(shpnt), getphase(shpnt)==P_MSGI); i++) ! 1855: buffer[2+i]=GETPORT(SCSIDAT); ! 1856: ! 1857: #if defined(DEBUG_MSGI) ! 1858: if(HOSTDATA(shpnt)->debug & debug_msgi) ! 1859: print_msg(buffer); ! 1860: #endif ! 1861: ! 1862: switch(buffer [2]) ! 1863: { ! 1864: case EXTENDED_SDTR: ! 1865: { ! 1866: long ticks; ! 1867: ! 1868: if(buffer[1]!=3) ! 1869: aha152x_panic(shpnt, "SDTR message length != 3"); ! 1870: ! 1871: if(!HOSTDATA(shpnt)->synchronous) ! 1872: break; ! 1873: ! 1874: printk("inbound SDTR: "); print_msg(buffer); ! 1875: ! 1876: ticks=(buffer[3]*4+49)/50; ! 1877: ! 1878: if(CURRENT_SC->SCp.phase & in_sync) ! 1879: { ! 1880: /* we initiated SDTR */ ! 1881: if(ticks>9 || buffer[4]<1 || buffer[4]>8) ! 1882: aha152x_panic(shpnt, "received SDTR invalid"); ! 1883: ! 1884: SYNCRATE |= ((ticks-2)<<4) + buffer[4]; ! 1885: } ! 1886: else if(ticks<=9 && buffer[4]>=1) ! 1887: { ! 1888: if(buffer[4]>8) ! 1889: buffer[4]=8; ! 1890: ! 1891: ADDMSG(EXTENDED_MESSAGE); ! 1892: ADDMSG(3); ! 1893: ADDMSG(EXTENDED_SDTR); ! 1894: if(ticks<4) ! 1895: { ! 1896: ticks=4; ! 1897: ADDMSG(50); ! 1898: } ! 1899: else ! 1900: ADDMSG(buffer[3]); ! 1901: ! 1902: ADDMSG(buffer[4]); ! 1903: ! 1904: printk("outbound SDTR: "); ! 1905: print_msg(&MSG(MSGLEN-5)); ! 1906: ! 1907: CURRENT_SC->SCp.phase |= in_sync; ! 1908: ! 1909: SYNCRATE |= ((ticks-2)<<4) + buffer[4]; ! 1910: ! 1911: start_sync++; ! 1912: } ! 1913: else ! 1914: { ! 1915: /* requested SDTR is too slow, do it asynchronously */ ! 1916: ADDMSG(MESSAGE_REJECT); ! 1917: SYNCRATE = 0; ! 1918: } ! 1919: ! 1920: SETPORT(SCSIRATE, SYNCRATE&0x7f); ! 1921: } ! 1922: break; ! 1923: ! 1924: case EXTENDED_MODIFY_DATA_POINTER: ! 1925: case EXTENDED_EXTENDED_IDENTIFY: ! 1926: case EXTENDED_WDTR: ! 1927: default: ! 1928: ADDMSG(MESSAGE_REJECT); ! 1929: break; ! 1930: } ! 1931: } ! 1932: break; ! 1933: ! 1934: default: ! 1935: printk("unsupported inbound message %x, ", ! 1936: CURRENT_SC->SCp.Message); ! 1937: break; ! 1938: ! 1939: } ! 1940: ! 1941: make_acklow(shpnt); ! 1942: phase=getphase(shpnt); ! 1943: } ! 1944: ! 1945: if(start_sync) ! 1946: CURRENT_SC->SCp.phase |= in_sync; ! 1947: else ! 1948: CURRENT_SC->SCp.phase &= ~in_sync; ! 1949: ! 1950: if(MSGLEN>0) ! 1951: SETPORT(SCSISIG, P_MSGI|ATNO); ! 1952: ! 1953: /* clear SCSI fifo on BUSFREE */ ! 1954: if(phase==P_BUSFREE) ! 1955: SETPORT(SXFRCTL0, CH1|CLRCH1); ! 1956: ! 1957: if(CURRENT_SC->SCp.phase & disconnected) ! 1958: { ! 1959: save_flags(flags); ! 1960: cli(); ! 1961: #if defined(DEBUG_QUEUES) ! 1962: if(HOSTDATA(shpnt)->debug & debug_queues) ! 1963: printk("d+, "); ! 1964: #endif ! 1965: append_SC(&DISCONNECTED_SC, CURRENT_SC); ! 1966: CURRENT_SC->SCp.phase |= 1<<16; ! 1967: CURRENT_SC = NULL; ! 1968: restore_flags(flags); ! 1969: ! 1970: SETBITS(SCSISEQ, ENRESELI); ! 1971: ! 1972: SETPORT(SIMODE0, DISCONNECTED_SC ? ENSELDI : 0); ! 1973: SETPORT(SIMODE1, ISSUE_SC ? ENBUSFREE : 0); ! 1974: ! 1975: SETBITS(DMACNTRL0, INTEN); ! 1976: return; ! 1977: } ! 1978: } ! 1979: break; ! 1980: ! 1981: case P_STATUS: /* STATUS IN phase */ ! 1982: #if defined(DEBUG_STATUS) || defined(DEBUG_INTR) || defined(DEBUG_PHASES) ! 1983: if(HOSTDATA(shpnt)->debug & (debug_status|debug_intr|debug_phases)) ! 1984: printk("STATUS, "); ! 1985: #endif ! 1986: SETPORT(SXFRCTL0, CH1); ! 1987: ! 1988: SETPORT(SIMODE0, 0); ! 1989: SETPORT(SIMODE1, ENREQINIT|ENBUSFREE); ! 1990: ! 1991: if(TESTHI(SSTAT1, PHASEMIS)) ! 1992: printk("aha152x: passing STATUS phase"); ! 1993: ! 1994: CURRENT_SC->SCp.Status = GETPORT(SCSIBUS); ! 1995: make_acklow(shpnt); ! 1996: getphase(shpnt); ! 1997: ! 1998: #if defined(DEBUG_STATUS) ! 1999: if(HOSTDATA(shpnt)->debug & debug_status) ! 2000: { ! 2001: printk("inbound status "); ! 2002: print_status(CURRENT_SC->SCp.Status); ! 2003: printk(", "); ! 2004: } ! 2005: #endif ! 2006: break; ! 2007: ! 2008: case P_DATAI: /* DATA IN phase */ ! 2009: { ! 2010: int fifodata, data_count, done; ! 2011: ! 2012: #if defined(DEBUG_DATAI) || defined(DEBUG_INTR) || defined(DEBUG_PHASES) ! 2013: if(HOSTDATA(shpnt)->debug & (debug_datai|debug_intr|debug_phases)) ! 2014: printk("DATA IN, "); ! 2015: #endif ! 2016: ! 2017: #if 0 ! 2018: if(GETPORT(FIFOSTAT) || GETPORT(SSTAT2) & (SFULL|SFCNT)) ! 2019: printk("aha152x: P_DATAI: %d(%d) bytes left in FIFO, resetting\n", ! 2020: GETPORT(FIFOSTAT), GETPORT(SSTAT2) & (SFULL|SFCNT)); ! 2021: #endif ! 2022: ! 2023: /* reset host fifo */ ! 2024: SETPORT(DMACNTRL0, RSTFIFO); ! 2025: SETPORT(DMACNTRL0, RSTFIFO|ENDMA); ! 2026: ! 2027: SETPORT(SXFRCTL0, CH1|SCSIEN|DMAEN); ! 2028: ! 2029: SETPORT(SIMODE0, 0); ! 2030: SETPORT(SIMODE1, ENPHASEMIS|ENBUSFREE); ! 2031: ! 2032: /* done is set when the FIFO is empty after the target left DATA IN */ ! 2033: done=0; ! 2034: ! 2035: /* while the target stays in DATA to transfer data */ ! 2036: while (!done) ! 2037: { ! 2038: #if defined(DEBUG_DATAI) ! 2039: if(HOSTDATA(shpnt)->debug & debug_datai) ! 2040: printk("expecting data, "); ! 2041: #endif ! 2042: /* wait for PHASEMIS or full FIFO */ ! 2043: while(TESTLO (DMASTAT, DFIFOFULL|INTSTAT)) ! 2044: barrier(); ! 2045: ! 2046: #if defined(DEBUG_DATAI) ! 2047: if(HOSTDATA(shpnt)->debug & debug_datai) ! 2048: printk("ok, "); ! 2049: #endif ! 2050: ! 2051: if(TESTHI(DMASTAT, DFIFOFULL)) ! 2052: fifodata=GETPORT(FIFOSTAT); ! 2053: else ! 2054: { ! 2055: /* wait for SCSI fifo to get empty */ ! 2056: while(TESTLO(SSTAT2, SEMPTY)) ! 2057: barrier(); ! 2058: ! 2059: /* rest of data in FIFO */ ! 2060: fifodata=GETPORT(FIFOSTAT); ! 2061: #if defined(DEBUG_DATAI) ! 2062: if(HOSTDATA(shpnt)->debug & debug_datai) ! 2063: printk("last transfer, "); ! 2064: #endif ! 2065: done=1; ! 2066: } ! 2067: ! 2068: #if defined(DEBUG_DATAI) ! 2069: if(HOSTDATA(shpnt)->debug & debug_datai) ! 2070: printk("fifodata=%d, ", fifodata); ! 2071: #endif ! 2072: ! 2073: while(fifodata && CURRENT_SC->SCp.this_residual) ! 2074: { ! 2075: data_count=fifodata; ! 2076: ! 2077: /* limit data transfer to size of first sg buffer */ ! 2078: if (data_count > CURRENT_SC->SCp.this_residual) ! 2079: data_count = CURRENT_SC->SCp.this_residual; ! 2080: ! 2081: fifodata -= data_count; ! 2082: ! 2083: #if defined(DEBUG_DATAI) ! 2084: if(HOSTDATA(shpnt)->debug & debug_datai) ! 2085: printk("data_count=%d, ", data_count); ! 2086: #endif ! 2087: ! 2088: if(data_count&1) ! 2089: { ! 2090: /* get a single byte in byte mode */ ! 2091: SETBITS(DMACNTRL0, _8BIT); ! 2092: *CURRENT_SC->SCp.ptr++ = GETPORT(DATAPORT); ! 2093: CURRENT_SC->SCp.this_residual--; ! 2094: } ! 2095: if(data_count>1) ! 2096: { ! 2097: CLRBITS(DMACNTRL0, _8BIT); ! 2098: data_count >>= 1; /* Number of words */ ! 2099: insw(DATAPORT, CURRENT_SC->SCp.ptr, data_count); ! 2100: #if defined(DEBUG_DATAI) ! 2101: if(HOSTDATA(shpnt)->debug & debug_datai) ! 2102: /* show what comes with the last transfer */ ! 2103: if(done) ! 2104: { ! 2105: #ifdef 0 ! 2106: int i; ! 2107: unsigned char *data; ! 2108: #endif ! 2109: ! 2110: printk("data on last transfer (%d bytes) ", ! 2111: 2*data_count); ! 2112: #ifdef 0 ! 2113: printk("data on last transfer (%d bytes: ", ! 2114: 2*data_count); ! 2115: data = (unsigned char *) CURRENT_SC->SCp.ptr; ! 2116: for(i=0; i<2*data_count; i++) ! 2117: printk("%2x ", *data++); ! 2118: printk("), "); ! 2119: #endif ! 2120: } ! 2121: #endif ! 2122: CURRENT_SC->SCp.ptr += 2 * data_count; ! 2123: CURRENT_SC->SCp.this_residual -= 2 * data_count; ! 2124: } ! 2125: ! 2126: /* if this buffer is full and there are more buffers left */ ! 2127: if (!CURRENT_SC->SCp.this_residual && ! 2128: CURRENT_SC->SCp.buffers_residual) ! 2129: { ! 2130: /* advance to next buffer */ ! 2131: CURRENT_SC->SCp.buffers_residual--; ! 2132: CURRENT_SC->SCp.buffer++; ! 2133: CURRENT_SC->SCp.ptr = ! 2134: CURRENT_SC->SCp.buffer->address; ! 2135: CURRENT_SC->SCp.this_residual = ! 2136: CURRENT_SC->SCp.buffer->length; ! 2137: } ! 2138: } ! 2139: ! 2140: /* ! 2141: * Fifo should be empty ! 2142: */ ! 2143: if(fifodata>0) ! 2144: { ! 2145: printk("aha152x: more data than expected (%d bytes)\n", ! 2146: GETPORT(FIFOSTAT)); ! 2147: SETBITS(DMACNTRL0, _8BIT); ! 2148: printk("aha152x: data ("); ! 2149: while(fifodata--) ! 2150: printk("%2x ", GETPORT(DATAPORT)); ! 2151: printk(")\n"); ! 2152: } ! 2153: ! 2154: #if defined(DEBUG_DATAI) ! 2155: if(HOSTDATA(shpnt)->debug & debug_datai) ! 2156: if(!fifodata) ! 2157: printk("fifo empty, "); ! 2158: else ! 2159: printk("something left in fifo, "); ! 2160: #endif ! 2161: } ! 2162: ! 2163: #if defined(DEBUG_DATAI) ! 2164: if((HOSTDATA(shpnt)->debug & debug_datai) && ! 2165: (CURRENT_SC->SCp.buffers_residual || ! 2166: CURRENT_SC->SCp.this_residual)) ! 2167: printk("left buffers (buffers=%d, bytes=%d), ", ! 2168: CURRENT_SC->SCp.buffers_residual, ! 2169: CURRENT_SC->SCp.this_residual); ! 2170: #endif ! 2171: /* transfer can be considered ended, when SCSIEN reads back zero */ ! 2172: CLRBITS(SXFRCTL0, SCSIEN|DMAEN); ! 2173: while(TESTHI(SXFRCTL0, SCSIEN)) ! 2174: barrier(); ! 2175: CLRBITS(DMACNTRL0, ENDMA); ! 2176: ! 2177: #if defined(DEBUG_DATAI) || defined(DEBUG_INTR) ! 2178: if(HOSTDATA(shpnt)->debug & (debug_datai|debug_intr)) ! 2179: printk("got %d bytes, ", GETSTCNT()); ! 2180: #endif ! 2181: ! 2182: CURRENT_SC->SCp.have_data_in++; ! 2183: } ! 2184: break; ! 2185: ! 2186: case P_DATAO: /* DATA OUT phase */ ! 2187: { ! 2188: int data_count; ! 2189: ! 2190: #if defined(DEBUG_DATAO) || defined(DEBUG_INTR) || defined(DEBUG_PHASES) ! 2191: if(HOSTDATA(shpnt)->debug & (debug_datao|debug_intr|debug_phases)) ! 2192: printk("DATA OUT, "); ! 2193: #endif ! 2194: #if defined(DEBUG_DATAO) ! 2195: if(HOSTDATA(shpnt)->debug & debug_datao) ! 2196: printk("got data to send (bytes=%d, buffers=%d), ", ! 2197: CURRENT_SC->SCp.this_residual, ! 2198: CURRENT_SC->SCp.buffers_residual); ! 2199: #endif ! 2200: ! 2201: if(GETPORT(FIFOSTAT) || GETPORT(SSTAT2) & (SFULL|SFCNT)) ! 2202: { ! 2203: printk("%d(%d) left in FIFO, ", ! 2204: GETPORT(FIFOSTAT), GETPORT(SSTAT2) & (SFULL|SFCNT)); ! 2205: aha152x_panic(shpnt, "FIFO should be empty"); ! 2206: } ! 2207: ! 2208: SETPORT(SXFRCTL0, CH1|CLRSTCNT|CLRCH1); ! 2209: SETPORT(SXFRCTL0, SCSIEN|DMAEN|CH1); ! 2210: ! 2211: SETPORT(DMACNTRL0, WRITE_READ|RSTFIFO); ! 2212: SETPORT(DMACNTRL0, ENDMA|WRITE_READ); ! 2213: ! 2214: SETPORT(SIMODE0, 0); ! 2215: SETPORT(SIMODE1, ENPHASEMIS|ENBUSFREE); ! 2216: ! 2217: /* while current buffer is not empty or ! 2218: there are more buffers to transfer */ ! 2219: while(TESTLO(SSTAT1, PHASEMIS) && ! 2220: (CURRENT_SC->SCp.this_residual || ! 2221: CURRENT_SC->SCp.buffers_residual)) ! 2222: { ! 2223: #if defined(DEBUG_DATAO) ! 2224: if(HOSTDATA(shpnt)->debug & debug_datao) ! 2225: printk("sending data (left: bytes=%d, buffers=%d), waiting, ", ! 2226: CURRENT_SC->SCp.this_residual, ! 2227: CURRENT_SC->SCp.buffers_residual); ! 2228: #endif ! 2229: /* transfer rest of buffer, but max. 128 byte */ ! 2230: data_count = ! 2231: CURRENT_SC->SCp.this_residual > 128 ? ! 2232: 128 : CURRENT_SC->SCp.this_residual ; ! 2233: ! 2234: #if defined(DEBUG_DATAO) ! 2235: if(HOSTDATA(shpnt)->debug & debug_datao) ! 2236: printk("data_count=%d, ", data_count); ! 2237: #endif ! 2238: ! 2239: if(data_count&1) ! 2240: { ! 2241: /* put a single byte in byte mode */ ! 2242: SETBITS(DMACNTRL0, _8BIT); ! 2243: SETPORT(DATAPORT, *CURRENT_SC->SCp.ptr++); ! 2244: CURRENT_SC->SCp.this_residual--; ! 2245: } ! 2246: if(data_count>1) ! 2247: { ! 2248: CLRBITS(DMACNTRL0, _8BIT); ! 2249: data_count >>= 1; /* number of words */ ! 2250: outsw(DATAPORT, CURRENT_SC->SCp.ptr, data_count); ! 2251: CURRENT_SC->SCp.ptr += 2 * data_count; ! 2252: CURRENT_SC->SCp.this_residual -= 2 * data_count; ! 2253: } ! 2254: ! 2255: /* wait for FIFO to get empty */ ! 2256: while(TESTLO(DMASTAT, DFIFOEMP|INTSTAT)) ! 2257: barrier(); ! 2258: ! 2259: #if defined(DEBUG_DATAO) ! 2260: if(HOSTDATA(shpnt)->debug & debug_datao) ! 2261: printk("fifo (%d bytes), transfered (%d bytes), ", ! 2262: GETPORT(FIFOSTAT), GETSTCNT()); ! 2263: #endif ! 2264: ! 2265: /* if this buffer is empty and there are more buffers left */ ! 2266: if (TESTLO(SSTAT1, PHASEMIS) && ! 2267: !CURRENT_SC->SCp.this_residual && ! 2268: CURRENT_SC->SCp.buffers_residual) ! 2269: { ! 2270: /* advance to next buffer */ ! 2271: CURRENT_SC->SCp.buffers_residual--; ! 2272: CURRENT_SC->SCp.buffer++; ! 2273: CURRENT_SC->SCp.ptr = ! 2274: CURRENT_SC->SCp.buffer->address; ! 2275: CURRENT_SC->SCp.this_residual = ! 2276: CURRENT_SC->SCp.buffer->length; ! 2277: } ! 2278: } ! 2279: ! 2280: if (CURRENT_SC->SCp.this_residual || CURRENT_SC->SCp.buffers_residual) ! 2281: { ! 2282: /* target leaves DATA OUT for an other phase ! 2283: (perhaps disconnect) */ ! 2284: ! 2285: /* data in fifos has to be resend */ ! 2286: data_count = GETPORT(SSTAT2) & (SFULL|SFCNT); ! 2287: ! 2288: data_count += GETPORT(FIFOSTAT) ; ! 2289: CURRENT_SC->SCp.ptr -= data_count; ! 2290: CURRENT_SC->SCp.this_residual += data_count; ! 2291: #if defined(DEBUG_DATAO) ! 2292: if(HOSTDATA(shpnt)->debug & debug_datao) ! 2293: printk("left data (bytes=%d, buffers=%d), fifos (bytes=%d), " ! 2294: "transfer incomplete, resetting fifo, ", ! 2295: CURRENT_SC->SCp.this_residual, ! 2296: CURRENT_SC->SCp.buffers_residual, ! 2297: data_count); ! 2298: #endif ! 2299: SETPORT(DMACNTRL0, WRITE_READ|RSTFIFO); ! 2300: CLRBITS(SXFRCTL0, SCSIEN|DMAEN); ! 2301: CLRBITS(DMACNTRL0, ENDMA); ! 2302: } ! 2303: else ! 2304: { ! 2305: #if defined(DEBUG_DATAO) ! 2306: if(HOSTDATA(shpnt)->debug & debug_datao) ! 2307: printk("waiting for SCSI fifo to get empty, "); ! 2308: #endif ! 2309: /* wait for SCSI fifo to get empty */ ! 2310: while(TESTLO(SSTAT2, SEMPTY)) ! 2311: barrier(); ! 2312: #if defined(DEBUG_DATAO) ! 2313: if(HOSTDATA(shpnt)->debug & debug_datao) ! 2314: printk("ok, left data (bytes=%d, buffers=%d) ", ! 2315: CURRENT_SC->SCp.this_residual, ! 2316: CURRENT_SC->SCp.buffers_residual); ! 2317: #endif ! 2318: CLRBITS(SXFRCTL0, SCSIEN|DMAEN); ! 2319: ! 2320: /* transfer can be considered ended, when SCSIEN reads back zero */ ! 2321: while(TESTHI(SXFRCTL0, SCSIEN)) ! 2322: barrier(); ! 2323: ! 2324: CLRBITS(DMACNTRL0, ENDMA); ! 2325: } ! 2326: ! 2327: #if defined(DEBUG_DATAO) || defined(DEBUG_INTR) ! 2328: if(HOSTDATA(shpnt)->debug & (debug_datao|debug_intr)) ! 2329: printk("sent %d data bytes, ", GETSTCNT()); ! 2330: #endif ! 2331: } ! 2332: break; ! 2333: ! 2334: case P_BUSFREE: /* BUSFREE */ ! 2335: #if defined(DEBUG_RACE) ! 2336: leave_driver("(BUSFREE) intr"); ! 2337: #endif ! 2338: #if defined(DEBUG_PHASES) ! 2339: if(HOSTDATA(shpnt)->debug & debug_phases) ! 2340: printk("unexpected BUS FREE, "); ! 2341: #endif ! 2342: CURRENT_SC->SCp.phase &= ~(P_MASK<<16); ! 2343: ! 2344: aha152x_done(shpnt, DID_ERROR << 16); /* Don't know any better */ ! 2345: return; ! 2346: break; ! 2347: ! 2348: case P_PARITY: /* parity error in DATA phase */ ! 2349: #if defined(DEBUG_RACE) ! 2350: leave_driver("(DID_PARITY) intr"); ! 2351: #endif ! 2352: printk("PARITY error in DATA phase, "); ! 2353: ! 2354: CURRENT_SC->SCp.phase &= ~(P_MASK<<16); ! 2355: ! 2356: SETBITS(DMACNTRL0, INTEN); ! 2357: aha152x_done(shpnt, DID_PARITY << 16); ! 2358: return; ! 2359: break; ! 2360: ! 2361: default: ! 2362: printk("aha152x: unexpected phase\n"); ! 2363: break; ! 2364: } ! 2365: ! 2366: if(done) ! 2367: { ! 2368: #if defined(DEBUG_INTR) ! 2369: if(HOSTDATA(shpnt)->debug & debug_intr) ! 2370: printk("command done.\n"); ! 2371: #endif ! 2372: #if defined(DEBUG_RACE) ! 2373: leave_driver("(done) intr"); ! 2374: #endif ! 2375: ! 2376: SETPORT(SIMODE0, DISCONNECTED_SC ? ENSELDI : 0); ! 2377: SETPORT(SIMODE1, ISSUE_SC ? ENBUSFREE : 0); ! 2378: SETPORT(SCSISEQ, DISCONNECTED_SC ? ENRESELI : 0); ! 2379: ! 2380: SETBITS(DMACNTRL0, INTEN); ! 2381: ! 2382: aha152x_done(shpnt, ! 2383: (CURRENT_SC->SCp.Status & 0xff) ! 2384: | ((CURRENT_SC->SCp.Message & 0xff) << 8) ! 2385: | (DID_OK << 16)); ! 2386: ! 2387: #if defined(DEBUG_RACE) ! 2388: printk("done returned (DID_OK: Status=%x; Message=%x).\n", ! 2389: CURRENT_SC->SCp.Status, CURRENT_SC->SCp.Message); ! 2390: #endif ! 2391: return; ! 2392: } ! 2393: ! 2394: if(CURRENT_SC) ! 2395: CURRENT_SC->SCp.phase |= 1<<16 ; ! 2396: ! 2397: SETPORT(SIMODE0, 0); ! 2398: SETPORT(SIMODE1, ENPHASEMIS|ENBUSFREE); ! 2399: #if defined(DEBUG_INTR) ! 2400: if(HOSTDATA(shpnt)->debug & debug_intr) ! 2401: disp_enintr(shpnt); ! 2402: #endif ! 2403: #if defined(DEBUG_RACE) ! 2404: leave_driver("(PHASEEND) intr"); ! 2405: #endif ! 2406: ! 2407: SETBITS(DMACNTRL0, INTEN); ! 2408: return; ! 2409: } ! 2410: ! 2411: /* ! 2412: * Dump the current driver status and panic... ! 2413: */ ! 2414: static void aha152x_panic(struct Scsi_Host *shpnt, char *msg) ! 2415: { ! 2416: printk("\naha152x: %s\n", msg); ! 2417: show_queues(shpnt); ! 2418: panic("aha152x panic"); ! 2419: } ! 2420: ! 2421: /* ! 2422: * Display registers of AIC-6260 ! 2423: */ ! 2424: static void disp_ports(struct Scsi_Host *shpnt) ! 2425: { ! 2426: #ifdef DEBUG_AHA152X ! 2427: int s; ! 2428: ! 2429: #ifdef SKIP_PORTS ! 2430: if(HOSTDATA(shpnt)->debug & debug_skipports) ! 2431: return; ! 2432: #endif ! 2433: ! 2434: printk("\n%s: ", CURRENT_SC ? "on bus" : "waiting"); ! 2435: ! 2436: s=GETPORT(SCSISEQ); ! 2437: printk("SCSISEQ ("); ! 2438: if(s & TEMODEO) printk("TARGET MODE "); ! 2439: if(s & ENSELO) printk("SELO "); ! 2440: if(s & ENSELI) printk("SELI "); ! 2441: if(s & ENRESELI) printk("RESELI "); ! 2442: if(s & ENAUTOATNO) printk("AUTOATNO "); ! 2443: if(s & ENAUTOATNI) printk("AUTOATNI "); ! 2444: if(s & ENAUTOATNP) printk("AUTOATNP "); ! 2445: if(s & SCSIRSTO) printk("SCSIRSTO "); ! 2446: printk(");"); ! 2447: ! 2448: printk(" SCSISIG ("); ! 2449: s=GETPORT(SCSISIG); ! 2450: switch(s & P_MASK) ! 2451: { ! 2452: case P_DATAO: ! 2453: printk("DATA OUT"); ! 2454: break; ! 2455: case P_DATAI: ! 2456: printk("DATA IN"); ! 2457: break; ! 2458: case P_CMD: ! 2459: printk("COMMAND"); ! 2460: break; ! 2461: case P_STATUS: ! 2462: printk("STATUS"); ! 2463: break; ! 2464: case P_MSGO: ! 2465: printk("MESSAGE OUT"); ! 2466: break; ! 2467: case P_MSGI: ! 2468: printk("MESSAGE IN"); ! 2469: break; ! 2470: default: ! 2471: printk("*illegal*"); ! 2472: break; ! 2473: } ! 2474: ! 2475: printk("); "); ! 2476: ! 2477: printk("INTSTAT (%s); ", TESTHI(DMASTAT, INTSTAT) ? "hi" : "lo"); ! 2478: ! 2479: printk("SSTAT ("); ! 2480: s=GETPORT(SSTAT0); ! 2481: if(s & TARGET) printk("TARGET "); ! 2482: if(s & SELDO) printk("SELDO "); ! 2483: if(s & SELDI) printk("SELDI "); ! 2484: if(s & SELINGO) printk("SELINGO "); ! 2485: if(s & SWRAP) printk("SWRAP "); ! 2486: if(s & SDONE) printk("SDONE "); ! 2487: if(s & SPIORDY) printk("SPIORDY "); ! 2488: if(s & DMADONE) printk("DMADONE "); ! 2489: ! 2490: s=GETPORT(SSTAT1); ! 2491: if(s & SELTO) printk("SELTO "); ! 2492: if(s & ATNTARG) printk("ATNTARG "); ! 2493: if(s & SCSIRSTI) printk("SCSIRSTI "); ! 2494: if(s & PHASEMIS) printk("PHASEMIS "); ! 2495: if(s & BUSFREE) printk("BUSFREE "); ! 2496: if(s & SCSIPERR) printk("SCSIPERR "); ! 2497: if(s & PHASECHG) printk("PHASECHG "); ! 2498: if(s & REQINIT) printk("REQINIT "); ! 2499: printk("); "); ! 2500: ! 2501: ! 2502: printk("SSTAT ("); ! 2503: ! 2504: s=GETPORT(SSTAT0) & GETPORT(SIMODE0); ! 2505: ! 2506: if(s & TARGET) printk("TARGET "); ! 2507: if(s & SELDO) printk("SELDO "); ! 2508: if(s & SELDI) printk("SELDI "); ! 2509: if(s & SELINGO) printk("SELINGO "); ! 2510: if(s & SWRAP) printk("SWRAP "); ! 2511: if(s & SDONE) printk("SDONE "); ! 2512: if(s & SPIORDY) printk("SPIORDY "); ! 2513: if(s & DMADONE) printk("DMADONE "); ! 2514: ! 2515: s=GETPORT(SSTAT1) & GETPORT(SIMODE1); ! 2516: ! 2517: if(s & SELTO) printk("SELTO "); ! 2518: if(s & ATNTARG) printk("ATNTARG "); ! 2519: if(s & SCSIRSTI) printk("SCSIRSTI "); ! 2520: if(s & PHASEMIS) printk("PHASEMIS "); ! 2521: if(s & BUSFREE) printk("BUSFREE "); ! 2522: if(s & SCSIPERR) printk("SCSIPERR "); ! 2523: if(s & PHASECHG) printk("PHASECHG "); ! 2524: if(s & REQINIT) printk("REQINIT "); ! 2525: printk("); "); ! 2526: ! 2527: printk("SXFRCTL0 ("); ! 2528: ! 2529: s=GETPORT(SXFRCTL0); ! 2530: if(s & SCSIEN) printk("SCSIEN "); ! 2531: if(s & DMAEN) printk("DMAEN "); ! 2532: if(s & CH1) printk("CH1 "); ! 2533: if(s & CLRSTCNT) printk("CLRSTCNT "); ! 2534: if(s & SPIOEN) printk("SPIOEN "); ! 2535: if(s & CLRCH1) printk("CLRCH1 "); ! 2536: printk("); "); ! 2537: ! 2538: printk("SIGNAL ("); ! 2539: ! 2540: s=GETPORT(SCSISIG); ! 2541: if(s & ATNI) printk("ATNI "); ! 2542: if(s & SELI) printk("SELI "); ! 2543: if(s & BSYI) printk("BSYI "); ! 2544: if(s & REQI) printk("REQI "); ! 2545: if(s & ACKI) printk("ACKI "); ! 2546: printk("); "); ! 2547: ! 2548: printk("SELID (%02x), ", GETPORT(SELID)); ! 2549: ! 2550: printk("SSTAT2 ("); ! 2551: ! 2552: s=GETPORT(SSTAT2); ! 2553: if(s & SOFFSET) printk("SOFFSET "); ! 2554: if(s & SEMPTY) printk("SEMPTY "); ! 2555: if(s & SFULL) printk("SFULL "); ! 2556: printk("); SFCNT (%d); ", s & (SFULL|SFCNT)); ! 2557: ! 2558: s=GETPORT(SSTAT3); ! 2559: printk("SCSICNT (%d), OFFCNT(%d), ", (s&0xf0)>>4, s&0x0f); ! 2560: ! 2561: printk("SSTAT4 ("); ! 2562: s=GETPORT(SSTAT4); ! 2563: if(s & SYNCERR) printk("SYNCERR "); ! 2564: if(s & FWERR) printk("FWERR "); ! 2565: if(s & FRERR) printk("FRERR "); ! 2566: printk("); "); ! 2567: ! 2568: printk("DMACNTRL0 ("); ! 2569: s=GETPORT(DMACNTRL0); ! 2570: printk("%s ", s & _8BIT ? "8BIT" : "16BIT"); ! 2571: printk("%s ", s & DMA ? "DMA" : "PIO" ); ! 2572: printk("%s ", s & WRITE_READ ? "WRITE" : "READ" ); ! 2573: if(s & ENDMA) printk("ENDMA "); ! 2574: if(s & INTEN) printk("INTEN "); ! 2575: if(s & RSTFIFO) printk("RSTFIFO "); ! 2576: if(s & SWINT) printk("SWINT "); ! 2577: printk("); "); ! 2578: ! 2579: ! 2580: #if 0 ! 2581: printk("DMACNTRL1 ("); ! 2582: ! 2583: s=GETPORT(DMACNTRL1); ! 2584: if(s & PWRDWN) printk("PWRDN "); ! 2585: printk("); "); ! 2586: ! 2587: ! 2588: printk("STK (%d); ", s & 0xf); ! 2589: ! 2590: #endif ! 2591: ! 2592: printk("DMASTAT ("); ! 2593: s=GETPORT(DMASTAT); ! 2594: if(s & ATDONE) printk("ATDONE "); ! 2595: if(s & WORDRDY) printk("WORDRDY "); ! 2596: if(s & DFIFOFULL) printk("DFIFOFULL "); ! 2597: if(s & DFIFOEMP) printk("DFIFOEMP "); ! 2598: printk(")"); ! 2599: ! 2600: printk("\n"); ! 2601: #endif ! 2602: } ! 2603: ! 2604: /* ! 2605: * display enabled interrupts ! 2606: */ ! 2607: static void disp_enintr(struct Scsi_Host *shpnt) ! 2608: { ! 2609: int s; ! 2610: ! 2611: printk("enabled interrupts ("); ! 2612: ! 2613: s=GETPORT(SIMODE0); ! 2614: if(s & ENSELDO) printk("ENSELDO "); ! 2615: if(s & ENSELDI) printk("ENSELDI "); ! 2616: if(s & ENSELINGO) printk("ENSELINGO "); ! 2617: if(s & ENSWRAP) printk("ENSWRAP "); ! 2618: if(s & ENSDONE) printk("ENSDONE "); ! 2619: if(s & ENSPIORDY) printk("ENSPIORDY "); ! 2620: if(s & ENDMADONE) printk("ENDMADONE "); ! 2621: ! 2622: s=GETPORT(SIMODE1); ! 2623: if(s & ENSELTIMO) printk("ENSELTIMO "); ! 2624: if(s & ENATNTARG) printk("ENATNTARG "); ! 2625: if(s & ENPHASEMIS) printk("ENPHASEMIS "); ! 2626: if(s & ENBUSFREE) printk("ENBUSFREE "); ! 2627: if(s & ENSCSIPERR) printk("ENSCSIPERR "); ! 2628: if(s & ENPHASECHG) printk("ENPHASECHG "); ! 2629: if(s & ENREQINIT) printk("ENREQINIT "); ! 2630: printk(")\n"); ! 2631: } ! 2632: ! 2633: #if defined(DEBUG_RACE) ! 2634: ! 2635: static const char *should_leave; ! 2636: static int in_driver=0; ! 2637: ! 2638: /* ! 2639: * Only one routine can be in the driver at once. ! 2640: */ ! 2641: static void enter_driver(const char *func) ! 2642: { ! 2643: unsigned long flags; ! 2644: ! 2645: save_flags(flags); ! 2646: cli(); ! 2647: printk("aha152x: entering %s() (%x)\n", func, jiffies); ! 2648: if(in_driver) ! 2649: { ! 2650: printk("%s should leave first.\n", should_leave); ! 2651: panic("aha152x: already in driver\n"); ! 2652: } ! 2653: ! 2654: in_driver++; ! 2655: should_leave=func; ! 2656: restore_flags(flags); ! 2657: } ! 2658: ! 2659: static void leave_driver(const char *func) ! 2660: { ! 2661: unsigned long flags; ! 2662: ! 2663: save_flags(flags); ! 2664: cli(); ! 2665: printk("\naha152x: leaving %s() (%x)\n", func, jiffies); ! 2666: if(!in_driver) ! 2667: { ! 2668: printk("aha152x: %s already left.\n", should_leave); ! 2669: panic("aha152x: %s already left driver.\n"); ! 2670: } ! 2671: ! 2672: in_driver--; ! 2673: should_leave=func; ! 2674: restore_flags(flags); ! 2675: } ! 2676: #endif ! 2677: ! 2678: /* ! 2679: * Show the command data of a command ! 2680: */ ! 2681: static void show_command(Scsi_Cmnd *ptr) ! 2682: { ! 2683: printk("0x%08x: target=%d; lun=%d; cmnd=(", ! 2684: (unsigned int) ptr, ptr->target, ptr->lun); ! 2685: ! 2686: print_command(ptr->cmnd); ! 2687: ! 2688: printk("); residual=%d; buffers=%d; phase |", ! 2689: ptr->SCp.this_residual, ptr->SCp.buffers_residual); ! 2690: ! 2691: if(ptr->SCp.phase & not_issued ) printk("not issued|"); ! 2692: if(ptr->SCp.phase & in_selection) printk("in selection|"); ! 2693: if(ptr->SCp.phase & disconnected) printk("disconnected|"); ! 2694: if(ptr->SCp.phase & aborted ) printk("aborted|"); ! 2695: if(ptr->SCp.phase & sent_ident ) printk("send_ident|"); ! 2696: if(ptr->SCp.phase & in_other) ! 2697: { ! 2698: printk("; in other("); ! 2699: switch((ptr->SCp.phase >> 16) & P_MASK) ! 2700: { ! 2701: case P_DATAO: ! 2702: printk("DATA OUT"); ! 2703: break; ! 2704: case P_DATAI: ! 2705: printk("DATA IN"); ! 2706: break; ! 2707: case P_CMD: ! 2708: printk("COMMAND"); ! 2709: break; ! 2710: case P_STATUS: ! 2711: printk("STATUS"); ! 2712: break; ! 2713: case P_MSGO: ! 2714: printk("MESSAGE OUT"); ! 2715: break; ! 2716: case P_MSGI: ! 2717: printk("MESSAGE IN"); ! 2718: break; ! 2719: default: ! 2720: printk("*illegal*"); ! 2721: break; ! 2722: } ! 2723: printk(")"); ! 2724: if(ptr->SCp.phase & (1<<16)) ! 2725: printk("; phaseend"); ! 2726: } ! 2727: printk("; next=0x%08x\n", (unsigned int) ptr->host_scribble); ! 2728: } ! 2729: ! 2730: /* ! 2731: * Dump the queued data ! 2732: */ ! 2733: static void show_queues(struct Scsi_Host *shpnt) ! 2734: { ! 2735: unsigned long flags; ! 2736: Scsi_Cmnd *ptr; ! 2737: ! 2738: save_flags(flags); ! 2739: cli(); ! 2740: printk("QUEUE STATUS:\nissue_SC:\n"); ! 2741: for(ptr=ISSUE_SC; ptr; ptr = (Scsi_Cmnd *) ptr->host_scribble) ! 2742: show_command(ptr); ! 2743: ! 2744: printk("current_SC:\n"); ! 2745: if(CURRENT_SC) ! 2746: show_command(CURRENT_SC); ! 2747: else ! 2748: printk("none\n"); ! 2749: ! 2750: printk("disconnected_SC:\n"); ! 2751: for(ptr=DISCONNECTED_SC; ptr; ptr = (Scsi_Cmnd *) ptr->host_scribble) ! 2752: show_command(ptr); ! 2753: ! 2754: disp_ports(shpnt); ! 2755: disp_enintr(shpnt); ! 2756: restore_flags(flags); ! 2757: } ! 2758: ! 2759: int aha152x_set_info(char *buffer, int length, struct Scsi_Host *shpnt) ! 2760: { ! 2761: return(-ENOSYS); /* Currently this is a no-op */ ! 2762: } ! 2763: ! 2764: #undef SPRINTF ! 2765: #define SPRINTF(args...) pos += sprintf(pos, ## args) ! 2766: ! 2767: static int get_command(char *pos, Scsi_Cmnd *ptr) ! 2768: { ! 2769: char *start = pos; ! 2770: int i; ! 2771: ! 2772: SPRINTF("0x%08x: target=%d; lun=%d; cmnd=(", ! 2773: (unsigned int) ptr, ptr->target, ptr->lun); ! 2774: ! 2775: for(i=0; i<COMMAND_SIZE(ptr->cmnd[0]); i++) ! 2776: SPRINTF("0x%02x", ptr->cmnd[i]); ! 2777: ! 2778: SPRINTF("); residual=%d; buffers=%d; phase |", ! 2779: ptr->SCp.this_residual, ptr->SCp.buffers_residual); ! 2780: ! 2781: if(ptr->SCp.phase & not_issued ) SPRINTF("not issued|"); ! 2782: if(ptr->SCp.phase & in_selection) SPRINTF("in selection|"); ! 2783: if(ptr->SCp.phase & disconnected) SPRINTF("disconnected|"); ! 2784: if(ptr->SCp.phase & aborted ) SPRINTF("aborted|"); ! 2785: if(ptr->SCp.phase & sent_ident ) SPRINTF("send_ident|"); ! 2786: if(ptr->SCp.phase & in_other) ! 2787: { ! 2788: SPRINTF("; in other("); ! 2789: switch((ptr->SCp.phase >> 16) & P_MASK) ! 2790: { ! 2791: case P_DATAO: ! 2792: SPRINTF("DATA OUT"); ! 2793: break; ! 2794: case P_DATAI: ! 2795: SPRINTF("DATA IN"); ! 2796: break; ! 2797: case P_CMD: ! 2798: SPRINTF("COMMAND"); ! 2799: break; ! 2800: case P_STATUS: ! 2801: SPRINTF("STATUS"); ! 2802: break; ! 2803: case P_MSGO: ! 2804: SPRINTF("MESSAGE OUT"); ! 2805: break; ! 2806: case P_MSGI: ! 2807: SPRINTF("MESSAGE IN"); ! 2808: break; ! 2809: default: ! 2810: SPRINTF("*illegal*"); ! 2811: break; ! 2812: } ! 2813: SPRINTF(")"); ! 2814: if(ptr->SCp.phase & (1<<16)) ! 2815: SPRINTF("; phaseend"); ! 2816: } ! 2817: SPRINTF("; next=0x%08x\n", (unsigned int) ptr->host_scribble); ! 2818: ! 2819: return(pos-start); ! 2820: } ! 2821: ! 2822: #undef SPRINTF ! 2823: #define SPRINTF(args...) do { if(pos < buffer + length) pos += sprintf(pos, ## args); } while(0) ! 2824: ! 2825: int aha152x_proc_info( ! 2826: char *buffer, ! 2827: char **start, ! 2828: off_t offset, ! 2829: int length, ! 2830: int hostno, ! 2831: int inout ! 2832: ) ! 2833: { ! 2834: int i; ! 2835: char *pos = buffer; ! 2836: Scsi_Device *scd; ! 2837: struct Scsi_Host *shpnt; ! 2838: unsigned long flags; ! 2839: Scsi_Cmnd *ptr; ! 2840: ! 2841: for(i=0, shpnt= (struct Scsi_Host *) NULL; i<IRQS; i++) ! 2842: if(aha152x_host[i] && aha152x_host[i]->host_no == hostno) ! 2843: shpnt=aha152x_host[i]; ! 2844: ! 2845: if(!shpnt) ! 2846: return(-ESRCH); ! 2847: ! 2848: if(inout) /* Has data been written to the file ? */ ! 2849: return(aha152x_set_info(buffer, length, shpnt)); ! 2850: ! 2851: SPRINTF(AHA152X_REVID "\n"); ! 2852: ! 2853: save_flags(flags); ! 2854: cli(); ! 2855: ! 2856: SPRINTF("vital data:\nioports 0x%04x to 0x%04x\n", ! 2857: shpnt->io_port, shpnt->io_port+shpnt->n_io_port-1); ! 2858: SPRINTF("interrupt 0x%02x\n", shpnt->irq); ! 2859: SPRINTF("disconnection/reconnection %s\n", ! 2860: HOSTDATA(shpnt)->reconnect ? "enabled" : "disabled"); ! 2861: SPRINTF("parity checking %s\n", ! 2862: HOSTDATA(shpnt)->parity ? "enabled" : "disabled"); ! 2863: SPRINTF("synchronous transfers %s\n", ! 2864: HOSTDATA(shpnt)->synchronous ? "enabled" : "disabled"); ! 2865: SPRINTF("current queued %d commands\n", ! 2866: HOSTDATA(shpnt)->commands); ! 2867: ! 2868: #if 0 ! 2869: SPRINTF("synchronously operating targets (tick=%ld ns):\n", ! 2870: 250000000/loops_per_sec); ! 2871: for(i=0; i<8; i++) ! 2872: if(HOSTDATA(shpnt)->syncrate[i]&0x7f) ! 2873: SPRINTF("target %d: period %dT/%ldns; req/ack offset %d\n", ! 2874: i, ! 2875: (((HOSTDATA(shpnt)->syncrate[i]&0x70)>>4)+2), ! 2876: (((HOSTDATA(shpnt)->syncrate[i]&0x70)>>4)+2)* ! 2877: 250000000/loops_per_sec, ! 2878: HOSTDATA(shpnt)->syncrate[i]&0x0f); ! 2879: #else ! 2880: SPRINTF("synchronously operating targets (tick=50 ns):\n"); ! 2881: for(i=0; i<8; i++) ! 2882: if(HOSTDATA(shpnt)->syncrate[i]&0x7f) ! 2883: SPRINTF("target %d: period %dT/%dns; req/ack offset %d\n", ! 2884: i, ! 2885: (((HOSTDATA(shpnt)->syncrate[i]&0x70)>>4)+2), ! 2886: (((HOSTDATA(shpnt)->syncrate[i]&0x70)>>4)+2)*50, ! 2887: HOSTDATA(shpnt)->syncrate[i]&0x0f); ! 2888: #endif ! 2889: ! 2890: #ifdef DEBUG_AHA152X ! 2891: #define PDEBUG(flags,txt) if(HOSTDATA(shpnt)->debug & flags) SPRINTF("(%s) ", txt); ! 2892: ! 2893: SPRINTF("enabled debugging options:\n"); ! 2894: ! 2895: PDEBUG(debug_skipports, "skip ports"); ! 2896: PDEBUG(debug_queue, "queue"); ! 2897: PDEBUG(debug_intr, "interrupt"); ! 2898: PDEBUG(debug_selection, "selection"); ! 2899: PDEBUG(debug_msgo, "message out"); ! 2900: PDEBUG(debug_msgi, "message in"); ! 2901: PDEBUG(debug_status, "status"); ! 2902: PDEBUG(debug_cmd, "command"); ! 2903: PDEBUG(debug_datai, "data in"); ! 2904: PDEBUG(debug_datao, "data out"); ! 2905: PDEBUG(debug_abort, "abort"); ! 2906: PDEBUG(debug_done, "done"); ! 2907: PDEBUG(debug_biosparam, "bios parameters"); ! 2908: PDEBUG(debug_phases, "phases"); ! 2909: PDEBUG(debug_queues, "queues"); ! 2910: PDEBUG(debug_reset, "reset"); ! 2911: ! 2912: SPRINTF("\n"); ! 2913: #endif ! 2914: ! 2915: SPRINTF("queue status:\nnot yet issued commands:\n"); ! 2916: for(ptr=ISSUE_SC; ptr; ptr = (Scsi_Cmnd *) ptr->host_scribble) ! 2917: pos += get_command(pos, ptr); ! 2918: ! 2919: if(CURRENT_SC) ! 2920: { ! 2921: SPRINTF("current command:\n"); ! 2922: pos += get_command(pos, CURRENT_SC); ! 2923: } ! 2924: ! 2925: SPRINTF("disconnected commands:\n"); ! 2926: for(ptr=DISCONNECTED_SC; ptr; ptr = (Scsi_Cmnd *) ptr->host_scribble) ! 2927: pos += get_command(pos, ptr); ! 2928: ! 2929: restore_flags(flags); ! 2930: ! 2931: scd = scsi_devices; ! 2932: ! 2933: SPRINTF("Attached devices: %s\n", (scd)?"":"none"); ! 2934: ! 2935: while (scd) { ! 2936: if (scd->host == shpnt) { ! 2937: ! 2938: SPRINTF("Channel: %02d Id: %02d Lun: %02d\n Vendor: ", ! 2939: scd->channel, scd->id, scd->lun); ! 2940: for (i=0; i<8; i++) { ! 2941: if (scd->vendor[i] >= 0x20) ! 2942: SPRINTF("%c", scd->vendor[i]); ! 2943: else ! 2944: SPRINTF(" "); ! 2945: } ! 2946: SPRINTF(" Model: "); ! 2947: for (i = 0; i < 16; i++) { ! 2948: if (scd->model[i] >= 0x20) ! 2949: SPRINTF("%c", scd->model[i]); ! 2950: else ! 2951: SPRINTF(" "); ! 2952: } ! 2953: SPRINTF(" Rev: "); ! 2954: for (i = 0; i < 4; i++) { ! 2955: if (scd->rev[i] >= 0x20) ! 2956: SPRINTF("%c", scd->rev[i]); ! 2957: else ! 2958: SPRINTF(" "); ! 2959: } ! 2960: SPRINTF("\n"); ! 2961: ! 2962: SPRINTF(" Type: %d ", scd->type); ! 2963: SPRINTF(" ANSI SCSI revision: %02x", ! 2964: (scd->scsi_level < 3)?1:2); ! 2965: ! 2966: if (scd->scsi_level == 2) ! 2967: SPRINTF(" CCS\n"); ! 2968: else ! 2969: SPRINTF("\n"); ! 2970: } ! 2971: scd = scd->next; ! 2972: } ! 2973: ! 2974: *start=buffer+offset; ! 2975: if (pos - buffer < offset) ! 2976: return 0; ! 2977: else if (pos - buffer - offset < length) ! 2978: return pos - buffer - offset; ! 2979: else ! 2980: return length; ! 2981: } ! 2982: ! 2983: #ifdef MODULE ! 2984: /* Eventually this will go into an include file, but this will be later */ ! 2985: Scsi_Host_Template driver_template = AHA152X; ! 2986: ! 2987: #include "scsi_module.c" ! 2988: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.