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