Annotation of Gnu-Mach/linux/src/drivers/scsi/qlogicisp.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * QLogic ISP1020 Intelligent SCSI Processor Driver (PCI)
                      3:  * Written by Erik H. Moe, [email protected]
                      4:  * Copyright 1995, Erik H. Moe
                      5:  *
                      6:  * This program is free software; you can redistribute it and/or modify it
                      7:  * under the terms of the GNU General Public License as published by the
                      8:  * Free Software Foundation; either version 2, or (at your option) any
                      9:  * later version.
                     10:  *
                     11:  * This program is distributed in the hope that it will be useful, but
                     12:  * WITHOUT ANY WARRANTY; without even the implied warranty of
                     13:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
                     14:  * General Public License for more details.
                     15:  */
                     16: 
                     17: /* Renamed and updated to 1.3.x by Michael Griffith <[email protected]> */
                     18: 
                     19: /*
                     20:  * $Date: 1999/04/26 05:54:52 $
                     21:  * $Revision: 1.1 $
                     22:  *
                     23:  * $Log: qlogicisp.c,v $
                     24:  * Revision 1.1  1999/04/26 05:54:52  tb
                     25:  * 1998-11-30  OKUJI Yoshinori  <[email protected]>
                     26:  *
                     27:  *     Clean up linux emulation code to make it architecture-independent
                     28:  *     as much as possible.
                     29:  *
                     30:  *     * linux: Renamed from linuxdev.
                     31:  *     * Makefile.in (objfiles): Add linux.o instead of linuxdev.o.
                     32:  *     (MAKE): New variable. Used for the linux.o target.
                     33:  *     * configure.in: Add AC_CHECK_TOOL(MAKE, make).
                     34:  *     * i386/i386/spl.h: Include <i386/ipl.h>, for compatibility with
                     35:  *     OSF Mach 3.0. Suggested by Elgin Lee <[email protected]>.
                     36:  *     * linux/src: Renamed from linux/linux.
                     37:  *     * linux/dev: Renamed from linux/mach.
                     38:  *     * linux/Drivers.in (AC_INIT): Use dev/include/linux/autoconf.h,
                     39:  *     instead of mach/include/linux/autoconf.h.
                     40:  *     * Makefile.in (all): Target ../linux.o instead of ../linuxdev.o.
                     41:  *     * linux/dev/drivers/block/genhd.c: Include <machine/spl.h> instead
                     42:  *     of <i386/ipl.h>.
                     43:  *     * linux/dev/drivers/net/auto_irq.c: Remove unneeded header files,
                     44:  *     <i386/ipl.h> and <i386/pic.h>.
                     45:  *     * linux/dev/init/main.c: Many i386-dependent codes moved to ...
                     46:  *     * linux/dev/arch/i386/irq.c: ... here.
                     47:  *     * linux/dev/arch/i386/setup.c: New file.
                     48:  *     * linux/dev/arch/i386/linux_emul.h: Likewise.
                     49:  *     * linux/dev/arch/i386/glue/timer.c: Merged into sched.c.
                     50:  *     * linux/dev/arch/i386/glue/sched.c: Include <machine/spl.h> instead
                     51:  *     of <i386/ipl.h>, and moved to ...
                     52:  *     * linux/dev/kernel/sched.c: ... here.
                     53:  *     * linux/dev/arch/i386/glue/block.c: Include <machine/spl.h> and
                     54:  *     <linux_emul.h>, instead of i386-dependent header files, and
                     55:  *     moved to ...
                     56:  *     * linux/dev/glue/blocl.c: ... here.
                     57:  *     * linux/dev/arch/i386/glue/net.c: Include <machine/spl.h> and
                     58:  *     <linux_emul.h>, instead of i386-dependent header files, and
                     59:  *     moved to ...
                     60:  *     * linux/dev/glue/net.c: ... here.
                     61:  *     * linux/dev/arch/i386/glue/misc.c: Remove `x86' and moved to ...
                     62:  *     * linux/dev/glue/misc.c: ... here.
                     63:  *     * linux/dev/arch/i386/glue/kmem.c: Moved to ...
                     64:  *     * linux/dev/glue/kmem.c: ... here.
                     65:  *
                     66:  * Revision 0.5  1995/09/22  02:23:15  root
                     67:  * do auto request sense
                     68:  *
                     69:  * Revision 0.4  1995/08/07  04:44:33  root
                     70:  * supply firmware with driver.
                     71:  * numerous bug fixes/general cleanup of code.
                     72:  *
                     73:  * Revision 0.3  1995/07/16  16:15:39  root
                     74:  * added reset/abort code.
                     75:  *
                     76:  * Revision 0.2  1995/06/29  03:14:19  root
                     77:  * fixed biosparam.
                     78:  * added queue protocol.
                     79:  *
                     80:  * Revision 0.1  1995/06/25  01:55:45  root
                     81:  * Initial release.
                     82:  *
                     83:  */
                     84: 
                     85: #include <linux/blk.h>
                     86: #include <linux/kernel.h>
                     87: #include <linux/string.h>
                     88: #include <linux/ioport.h>
                     89: #include <linux/sched.h>
                     90: #include <linux/types.h>
                     91: #include <linux/bios32.h>
                     92: #include <linux/pci.h>
                     93: #include <linux/delay.h>
                     94: #include <linux/unistd.h>
                     95: #include <asm/io.h>
                     96: #include <asm/irq.h>
                     97: 
                     98: #include "sd.h"
                     99: #include "hosts.h"
                    100: #include "qlogicisp.h"
                    101: 
                    102: /* Configuration section *****************************************************/
                    103: 
                    104: /* Set the following macro to 1 to reload the ISP1020's firmware.  This is
                    105:    the latest firmware provided by QLogic.  This may be an earlier/later
                    106:    revision than supplied by your board. */
                    107: 
                    108: #define RELOAD_FIRMWARE                1
                    109: 
                    110: /* Set the following macro to 1 to reload the ISP1020's defaults from nvram.
                    111:    If you are not sure of your settings, leave this alone, the driver will
                    112:    use a set of 'safe' defaults */
                    113: 
                    114: #define USE_NVRAM_DEFAULTS     0
                    115: 
                    116: /*  Macros used for debugging */
                    117: 
                    118: #define DEBUG_ISP1020          0
                    119: #define DEBUG_ISP1020_INT      0
                    120: #define DEBUG_ISP1020_SETUP    0
                    121: #define TRACE_ISP              0
                    122: 
                    123: #define DEFAULT_LOOP_COUNT     1000000
                    124: 
                    125: /* End Configuration section *************************************************/
                    126: 
                    127: #include <linux/module.h>
                    128: 
                    129: #if TRACE_ISP
                    130: 
                    131: # define TRACE_BUF_LEN (32*1024)
                    132: 
                    133: struct {
                    134:        u_long          next;
                    135:        struct {
                    136:                u_long          time;
                    137:                u_int           index;
                    138:                u_int           addr;
                    139:                u_char *        name;
                    140:        } buf[TRACE_BUF_LEN];
                    141: } trace;
                    142: 
                    143: #define TRACE(w, i, a)                                         \
                    144: {                                                              \
                    145:        unsigned long flags;                                    \
                    146:                                                                \
                    147:        save_flags(flags);                                      \
                    148:        cli();                                                  \
                    149:        trace.buf[trace.next].name  = (w);                      \
                    150:        trace.buf[trace.next].time  = jiffies;                  \
                    151:        trace.buf[trace.next].index = (i);                      \
                    152:        trace.buf[trace.next].addr  = (long) (a);               \
                    153:        trace.next = (trace.next + 1) & (TRACE_BUF_LEN - 1);    \
                    154:        restore_flags(flags);                                   \
                    155: }
                    156: 
                    157: #else
                    158: # define TRACE(w, i, a)
                    159: #endif
                    160: 
                    161: #if DEBUG_ISP1020
                    162: #define ENTER(x)       printk("isp1020 : entering %s()\n", x);
                    163: #define LEAVE(x)       printk("isp1020 : leaving %s()\n", x);
                    164: #define DEBUG(x)       x
                    165: #else
                    166: #define ENTER(x)
                    167: #define LEAVE(x)
                    168: #define DEBUG(x)
                    169: #endif /* DEBUG_ISP1020 */
                    170: 
                    171: #if DEBUG_ISP1020_INTR
                    172: #define ENTER_INTR(x)  printk("isp1020 : entering %s()\n", x);
                    173: #define LEAVE_INTR(x)  printk("isp1020 : leaving %s()\n", x);
                    174: #define DEBUG_INTR(x)  x
                    175: #else
                    176: #define ENTER_INTR(x)
                    177: #define LEAVE_INTR(x)
                    178: #define DEBUG_INTR(x)
                    179: #endif /* DEBUG ISP1020_INTR */
                    180: 
                    181: #define ISP1020_REV_ID 1
                    182: 
                    183: #define MAX_TARGETS    16
                    184: #define MAX_LUNS       8
                    185: 
                    186: /* host configuration and control registers */
                    187: #define HOST_HCCR      0xc0    /* host command and control */
                    188: 
                    189: /* pci bus interface registers */
                    190: #define PCI_ID_LOW     0x00    /* vendor id */
                    191: #define PCI_ID_HIGH    0x02    /* device id */
                    192: #define ISP_CFG0       0x04    /* configuration register #0 */
                    193: #define ISP_CFG1       0x06    /* configuration register #1 */
                    194: #define PCI_INTF_CTL   0x08    /* pci interface control */
                    195: #define PCI_INTF_STS   0x0a    /* pci interface status */
                    196: #define PCI_SEMAPHORE  0x0c    /* pci semaphore */
                    197: #define PCI_NVRAM      0x0e    /* pci nvram interface */
                    198: 
                    199: /* mailbox registers */
                    200: #define MBOX0          0x70    /* mailbox 0 */
                    201: #define MBOX1          0x72    /* mailbox 1 */
                    202: #define MBOX2          0x74    /* mailbox 2 */
                    203: #define MBOX3          0x76    /* mailbox 3 */
                    204: #define MBOX4          0x78    /* mailbox 4 */
                    205: #define MBOX5          0x7a    /* mailbox 5 */
                    206: 
                    207: /* mailbox command complete status codes */
                    208: #define MBOX_COMMAND_COMPLETE          0x4000
                    209: #define INVALID_COMMAND                        0x4001
                    210: #define HOST_INTERFACE_ERROR           0x4002
                    211: #define TEST_FAILED                    0x4003
                    212: #define COMMAND_ERROR                  0x4005
                    213: #define COMMAND_PARAM_ERROR            0x4006
                    214: 
                    215: /* async event status codes */
                    216: #define ASYNC_SCSI_BUS_RESET           0x8001
                    217: #define SYSTEM_ERROR                   0x8002
                    218: #define REQUEST_TRANSFER_ERROR         0x8003
                    219: #define RESPONSE_TRANSFER_ERROR                0x8004
                    220: #define REQUEST_QUEUE_WAKEUP           0x8005
                    221: #define EXECUTION_TIMEOUT_RESET                0x8006
                    222: 
                    223: struct Entry_header {
                    224:        u_char  entry_type;
                    225:        u_char  entry_cnt;
                    226:        u_char  sys_def_1;
                    227:        u_char  flags;
                    228: };
                    229: 
                    230: /* entry header type commands */
                    231: #define ENTRY_COMMAND          1
                    232: #define ENTRY_CONTINUATION     2
                    233: #define ENTRY_STATUS           3
                    234: #define ENTRY_MARKER           4
                    235: #define ENTRY_EXTENDED_COMMAND 5
                    236: 
                    237: /* entry header flag definitions */
                    238: #define EFLAG_CONTINUATION     1
                    239: #define EFLAG_BUSY             2
                    240: #define EFLAG_BAD_HEADER       4
                    241: #define EFLAG_BAD_PAYLOAD      8
                    242: 
                    243: struct dataseg {
                    244:        u_int                   d_base;
                    245:        u_int                   d_count;
                    246: };
                    247: 
                    248: struct Command_Entry {
                    249:        struct Entry_header     hdr;
                    250:        u_int                   handle;
                    251:        u_char                  target_lun;
                    252:        u_char                  target_id;
                    253:        u_short                 cdb_length;
                    254:        u_short                 control_flags;
                    255:        u_short                 rsvd;
                    256:        u_short                 time_out;
                    257:        u_short                 segment_cnt;
                    258:        u_char                  cdb[12];
                    259:        struct dataseg          dataseg[4];
                    260: };
                    261: 
                    262: /* command entry control flag definitions */
                    263: #define CFLAG_NODISC           0x01
                    264: #define CFLAG_HEAD_TAG         0x02
                    265: #define CFLAG_ORDERED_TAG      0x04
                    266: #define CFLAG_SIMPLE_TAG       0x08
                    267: #define CFLAG_TAR_RTN          0x10
                    268: #define CFLAG_READ             0x20
                    269: #define CFLAG_WRITE            0x40
                    270: 
                    271: struct Ext_Command_Entry {
                    272:        struct Entry_header     hdr;
                    273:        u_int                   handle;
                    274:        u_char                  target_lun;
                    275:        u_char                  target_id;
                    276:        u_short                 cdb_length;
                    277:        u_short                 control_flags;
                    278:        u_short                 rsvd;
                    279:        u_short                 time_out;
                    280:        u_short                 segment_cnt;
                    281:        u_char                  cdb[44];
                    282: };
                    283: 
                    284: struct Continuation_Entry {
                    285:        struct Entry_header     hdr;
                    286:        u_int                   reserved;
                    287:        struct dataseg          dataseg[7];
                    288: };
                    289: 
                    290: struct Marker_Entry {
                    291:        struct Entry_header     hdr;
                    292:        u_int                   reserved;
                    293:        u_char                  target_lun;
                    294:        u_char                  target_id;
                    295:        u_char                  modifier;
                    296:        u_char                  rsvd;
                    297:        u_char                  rsvds[52];
                    298: };
                    299: 
                    300: /* marker entry modifier definitions */
                    301: #define SYNC_DEVICE    0
                    302: #define SYNC_TARGET    1
                    303: #define SYNC_ALL       2
                    304: 
                    305: struct Status_Entry {
                    306:        struct Entry_header     hdr;
                    307:        u_int                   handle;
                    308:        u_short                 scsi_status;
                    309:        u_short                 completion_status;
                    310:        u_short                 state_flags;
                    311:        u_short                 status_flags;
                    312:        u_short                 time;
                    313:        u_short                 req_sense_len;
                    314:        u_int                   residual;
                    315:        u_char                  rsvd[8];
                    316:        u_char                  req_sense_data[32];
                    317: };
                    318: 
                    319: /* status entry completion status definitions */
                    320: #define CS_COMPLETE                    0x0000
                    321: #define CS_INCOMPLETE                  0x0001
                    322: #define CS_DMA_ERROR                   0x0002
                    323: #define CS_TRANSPORT_ERROR             0x0003
                    324: #define CS_RESET_OCCURRED              0x0004
                    325: #define CS_ABORTED                     0x0005
                    326: #define CS_TIMEOUT                     0x0006
                    327: #define CS_DATA_OVERRUN                        0x0007
                    328: #define CS_COMMAND_OVERRUN             0x0008
                    329: #define CS_STATUS_OVERRUN              0x0009
                    330: #define CS_BAD_MESSAGE                 0x000a
                    331: #define CS_NO_MESSAGE_OUT              0x000b
                    332: #define CS_EXT_ID_FAILED               0x000c
                    333: #define CS_IDE_MSG_FAILED              0x000d
                    334: #define CS_ABORT_MSG_FAILED            0x000e
                    335: #define CS_REJECT_MSG_FAILED           0x000f
                    336: #define CS_NOP_MSG_FAILED              0x0010
                    337: #define CS_PARITY_ERROR_MSG_FAILED     0x0011
                    338: #define CS_DEVICE_RESET_MSG_FAILED     0x0012
                    339: #define CS_ID_MSG_FAILED               0x0013
                    340: #define CS_UNEXP_BUS_FREE              0x0014
                    341: /* as per app note #83120-514-06a: */
                    342: #define CS_DATA_UNDERRUN               0x0015
                    343: #define CS_INVALID_ENTRY_TYPE          0x001b
                    344: #define CS_DEVICE_QUEUE_FULL           0x001c
                    345: #define CS_SCSI_PHASE_SKIPPED          0x001d
                    346: #define CS_ARS_FAILED                  0x001e  /* auto Req. Sense failed */
                    347: 
                    348: /* status entry state flag definitions */
                    349: #define SF_GOT_BUS                     0x0100
                    350: #define SF_GOT_TARGET                  0x0200
                    351: #define SF_SENT_CDB                    0x0400
                    352: #define SF_TRANSFERRED_DATA            0x0800
                    353: #define SF_GOT_STATUS                  0x1000
                    354: #define SF_GOT_SENSE                   0x2000
                    355: 
                    356: /* status entry status flag definitions */
                    357: #define STF_DISCONNECT                 0x0001
                    358: #define STF_SYNCHRONOUS                        0x0002
                    359: #define STF_PARITY_ERROR               0x0004
                    360: #define STF_BUS_RESET                  0x0008
                    361: #define STF_DEVICE_RESET               0x0010
                    362: #define STF_ABORTED                    0x0020
                    363: #define STF_TIMEOUT                    0x0040
                    364: #define STF_NEGOTIATION                        0x0080
                    365: 
                    366: /* interface control commands */
                    367: #define ISP_RESET                      0x0001
                    368: #define ISP_EN_INT                     0x0002
                    369: #define ISP_EN_RISC                    0x0004
                    370: 
                    371: /* host control commands */
                    372: #define HCCR_NOP                       0x0000
                    373: #define HCCR_RESET                     0x1000
                    374: #define HCCR_PAUSE                     0x2000
                    375: #define HCCR_RELEASE                   0x3000
                    376: #define HCCR_SINGLE_STEP               0x4000
                    377: #define HCCR_SET_HOST_INTR             0x5000
                    378: #define HCCR_CLEAR_HOST_INTR           0x6000
                    379: #define HCCR_CLEAR_RISC_INTR           0x7000
                    380: #define HCCR_BP_ENABLE                 0x8000
                    381: #define HCCR_BIOS_DISABLE              0x9000
                    382: #define HCCR_TEST_MODE                 0xf000
                    383: 
                    384: #define RISC_BUSY                      0x0004
                    385: 
                    386: /* mailbox commands */
                    387: #define MBOX_NO_OP                     0x0000
                    388: #define MBOX_LOAD_RAM                  0x0001
                    389: #define MBOX_EXEC_FIRMWARE             0x0002
                    390: #define MBOX_DUMP_RAM                  0x0003
                    391: #define MBOX_WRITE_RAM_WORD            0x0004
                    392: #define MBOX_READ_RAM_WORD             0x0005
                    393: #define MBOX_MAILBOX_REG_TEST          0x0006
                    394: #define MBOX_VERIFY_CHECKSUM           0x0007
                    395: #define MBOX_ABOUT_FIRMWARE            0x0008
                    396: #define MBOX_CHECK_FIRMWARE            0x000e
                    397: #define MBOX_INIT_REQ_QUEUE            0x0010
                    398: #define MBOX_INIT_RES_QUEUE            0x0011
                    399: #define MBOX_EXECUTE_IOCB              0x0012
                    400: #define MBOX_WAKE_UP                   0x0013
                    401: #define MBOX_STOP_FIRMWARE             0x0014
                    402: #define MBOX_ABORT                     0x0015
                    403: #define MBOX_ABORT_DEVICE              0x0016
                    404: #define MBOX_ABORT_TARGET              0x0017
                    405: #define MBOX_BUS_RESET                 0x0018
                    406: #define MBOX_STOP_QUEUE                        0x0019
                    407: #define MBOX_START_QUEUE               0x001a
                    408: #define MBOX_SINGLE_STEP_QUEUE         0x001b
                    409: #define MBOX_ABORT_QUEUE               0x001c
                    410: #define MBOX_GET_DEV_QUEUE_STATUS      0x001d
                    411: #define MBOX_GET_FIRMWARE_STATUS       0x001f
                    412: #define MBOX_GET_INIT_SCSI_ID          0x0020
                    413: #define MBOX_GET_SELECT_TIMEOUT                0x0021
                    414: #define MBOX_GET_RETRY_COUNT           0x0022
                    415: #define MBOX_GET_TAG_AGE_LIMIT         0x0023
                    416: #define MBOX_GET_CLOCK_RATE            0x0024
                    417: #define MBOX_GET_ACT_NEG_STATE         0x0025
                    418: #define MBOX_GET_ASYNC_DATA_SETUP_TIME 0x0026
                    419: #define MBOX_GET_PCI_PARAMS            0x0027
                    420: #define MBOX_GET_TARGET_PARAMS         0x0028
                    421: #define MBOX_GET_DEV_QUEUE_PARAMS      0x0029
                    422: #define MBOX_SET_INIT_SCSI_ID          0x0030
                    423: #define MBOX_SET_SELECT_TIMEOUT                0x0031
                    424: #define MBOX_SET_RETRY_COUNT           0x0032
                    425: #define MBOX_SET_TAG_AGE_LIMIT         0x0033
                    426: #define MBOX_SET_CLOCK_RATE            0x0034
                    427: #define MBOX_SET_ACTIVE_NEG_STATE      0x0035
                    428: #define MBOX_SET_ASYNC_DATA_SETUP_TIME 0x0036
                    429: #define MBOX_SET_PCI_CONTROL_PARAMS    0x0037
                    430: #define MBOX_SET_TARGET_PARAMS         0x0038
                    431: #define MBOX_SET_DEV_QUEUE_PARAMS      0x0039
                    432: #define MBOX_RETURN_BIOS_BLOCK_ADDR    0x0040
                    433: #define MBOX_WRITE_FOUR_RAM_WORDS      0x0041
                    434: #define MBOX_EXEC_BIOS_IOCB            0x0042
                    435: 
                    436: #include "qlogicisp_asm.c"
                    437: 
                    438: #define PACKB(a, b)                    (((a)<<4)|(b))
                    439: 
                    440: const u_char mbox_param[] = {
                    441:        PACKB(1, 1),    /* MBOX_NO_OP */
                    442:        PACKB(5, 5),    /* MBOX_LOAD_RAM */
                    443:        PACKB(2, 0),    /* MBOX_EXEC_FIRMWARE */
                    444:        PACKB(5, 5),    /* MBOX_DUMP_RAM */
                    445:        PACKB(3, 3),    /* MBOX_WRITE_RAM_WORD */
                    446:        PACKB(2, 3),    /* MBOX_READ_RAM_WORD */
                    447:        PACKB(6, 6),    /* MBOX_MAILBOX_REG_TEST */
                    448:        PACKB(2, 3),    /* MBOX_VERIFY_CHECKSUM */
                    449:        PACKB(1, 3),    /* MBOX_ABOUT_FIRMWARE */
                    450:        PACKB(0, 0),    /* 0x0009 */
                    451:        PACKB(0, 0),    /* 0x000a */
                    452:        PACKB(0, 0),    /* 0x000b */
                    453:        PACKB(0, 0),    /* 0x000c */
                    454:        PACKB(0, 0),    /* 0x000d */
                    455:        PACKB(1, 2),    /* MBOX_CHECK_FIRMWARE */
                    456:        PACKB(0, 0),    /* 0x000f */
                    457:        PACKB(5, 5),    /* MBOX_INIT_REQ_QUEUE */
                    458:        PACKB(6, 6),    /* MBOX_INIT_RES_QUEUE */
                    459:        PACKB(4, 4),    /* MBOX_EXECUTE_IOCB */
                    460:        PACKB(2, 2),    /* MBOX_WAKE_UP */
                    461:        PACKB(1, 6),    /* MBOX_STOP_FIRMWARE */
                    462:        PACKB(4, 4),    /* MBOX_ABORT */
                    463:        PACKB(2, 2),    /* MBOX_ABORT_DEVICE */
                    464:        PACKB(3, 3),    /* MBOX_ABORT_TARGET */
                    465:        PACKB(2, 2),    /* MBOX_BUS_RESET */
                    466:        PACKB(2, 3),    /* MBOX_STOP_QUEUE */
                    467:        PACKB(2, 3),    /* MBOX_START_QUEUE */
                    468:        PACKB(2, 3),    /* MBOX_SINGLE_STEP_QUEUE */
                    469:        PACKB(2, 3),    /* MBOX_ABORT_QUEUE */
                    470:        PACKB(2, 4),    /* MBOX_GET_DEV_QUEUE_STATUS */
                    471:        PACKB(0, 0),    /* 0x001e */
                    472:        PACKB(1, 3),    /* MBOX_GET_FIRMWARE_STATUS */
                    473:        PACKB(1, 2),    /* MBOX_GET_INIT_SCSI_ID */
                    474:        PACKB(1, 2),    /* MBOX_GET_SELECT_TIMEOUT */
                    475:        PACKB(1, 3),    /* MBOX_GET_RETRY_COUNT */
                    476:        PACKB(1, 2),    /* MBOX_GET_TAG_AGE_LIMIT */
                    477:        PACKB(1, 2),    /* MBOX_GET_CLOCK_RATE */
                    478:        PACKB(1, 2),    /* MBOX_GET_ACT_NEG_STATE */
                    479:        PACKB(1, 2),    /* MBOX_GET_ASYNC_DATA_SETUP_TIME */
                    480:        PACKB(1, 3),    /* MBOX_GET_PCI_PARAMS */
                    481:        PACKB(2, 4),    /* MBOX_GET_TARGET_PARAMS */
                    482:        PACKB(2, 4),    /* MBOX_GET_DEV_QUEUE_PARAMS */
                    483:        PACKB(0, 0),    /* 0x002a */
                    484:        PACKB(0, 0),    /* 0x002b */
                    485:        PACKB(0, 0),    /* 0x002c */
                    486:        PACKB(0, 0),    /* 0x002d */
                    487:        PACKB(0, 0),    /* 0x002e */
                    488:        PACKB(0, 0),    /* 0x002f */
                    489:        PACKB(2, 2),    /* MBOX_SET_INIT_SCSI_ID */
                    490:        PACKB(2, 2),    /* MBOX_SET_SELECT_TIMEOUT */
                    491:        PACKB(3, 3),    /* MBOX_SET_RETRY_COUNT */
                    492:        PACKB(2, 2),    /* MBOX_SET_TAG_AGE_LIMIT */
                    493:        PACKB(2, 2),    /* MBOX_SET_CLOCK_RATE */
                    494:        PACKB(2, 2),    /* MBOX_SET_ACTIVE_NEG_STATE */
                    495:        PACKB(2, 2),    /* MBOX_SET_ASYNC_DATA_SETUP_TIME */
                    496:        PACKB(3, 3),    /* MBOX_SET_PCI_CONTROL_PARAMS */
                    497:        PACKB(4, 4),    /* MBOX_SET_TARGET_PARAMS */
                    498:        PACKB(4, 4),    /* MBOX_SET_DEV_QUEUE_PARAMS */
                    499:        PACKB(0, 0),    /* 0x003a */
                    500:        PACKB(0, 0),    /* 0x003b */
                    501:        PACKB(0, 0),    /* 0x003c */
                    502:        PACKB(0, 0),    /* 0x003d */
                    503:        PACKB(0, 0),    /* 0x003e */
                    504:        PACKB(0, 0),    /* 0x003f */
                    505:        PACKB(1, 2),    /* MBOX_RETURN_BIOS_BLOCK_ADDR */
                    506:        PACKB(6, 1),    /* MBOX_WRITE_FOUR_RAM_WORDS */
                    507:        PACKB(2, 3)     /* MBOX_EXEC_BIOS_IOCB */
                    508: };
                    509: 
                    510: #define MAX_MBOX_COMMAND       (sizeof(mbox_param)/sizeof(u_short))
                    511: 
                    512: struct host_param {
                    513:        u_short         fifo_threshold;
                    514:        u_short         host_adapter_enable;
                    515:        u_short         initiator_scsi_id;
                    516:        u_short         bus_reset_delay;
                    517:        u_short         retry_count;
                    518:        u_short         retry_delay;
                    519:        u_short         async_data_setup_time;
                    520:        u_short         req_ack_active_negation;
                    521:        u_short         data_line_active_negation;
                    522:        u_short         data_dma_burst_enable;
                    523:        u_short         command_dma_burst_enable;
                    524:        u_short         tag_aging;
                    525:        u_short         selection_timeout;
                    526:        u_short         max_queue_depth;
                    527: };
                    528: 
                    529: /*
                    530:  * Device Flags:
                    531:  *
                    532:  * Bit  Name
                    533:  * ---------
                    534:  *  7   Disconnect Privilege
                    535:  *  6   Parity Checking
                    536:  *  5   Wide Data Transfers
                    537:  *  4   Synchronous Data Transfers
                    538:  *  3   Tagged Queuing
                    539:  *  2   Automatic Request Sense
                    540:  *  1   Stop Queue on Check Condition
                    541:  *  0   Renegotiate on Error
                    542:  */
                    543: 
                    544: struct dev_param {
                    545:        u_short         device_flags;
                    546:        u_short         execution_throttle;
                    547:        u_short         synchronous_period;
                    548:        u_short         synchronous_offset;
                    549:        u_short         device_enable;
                    550:        u_short         reserved; /* pad */
                    551: };
                    552: 
                    553: /*
                    554:  * The result queue can be quite a bit smaller since continuation entries
                    555:  * do not show up there:
                    556:  */
                    557: #define RES_QUEUE_LEN          ((QLOGICISP_REQ_QUEUE_LEN + 1) / 8 - 1)
                    558: #define QUEUE_ENTRY_LEN                64
                    559: 
                    560: struct isp1020_hostdata {
                    561:        u_char  bus;
                    562:        u_char  revision;
                    563:        u_char  device_fn;
                    564:        struct  host_param host_param;
                    565:        struct  dev_param dev_param[MAX_TARGETS];
                    566:        
                    567:        /* result and request queues (shared with isp1020): */
                    568:        u_int   req_in_ptr;             /* index of next request slot */
                    569:        u_int   res_out_ptr;            /* index of next result slot */
                    570: 
                    571:        /* this is here so the queues are nicely aligned */
                    572:        long    send_marker;            /* do we need to send a marker? */
                    573: 
                    574:        char    res[RES_QUEUE_LEN+1][QUEUE_ENTRY_LEN];
                    575:        char    req[QLOGICISP_REQ_QUEUE_LEN+1][QUEUE_ENTRY_LEN];
                    576: };
                    577: 
                    578: /* queue length's _must_ be power of two: */
                    579: #define QUEUE_DEPTH(in, out, ql)       ((in - out) & (ql))
                    580: #define REQ_QUEUE_DEPTH(in, out)       QUEUE_DEPTH(in, out,                 \
                    581:                                                    QLOGICISP_REQ_QUEUE_LEN)
                    582: #define RES_QUEUE_DEPTH(in, out)       QUEUE_DEPTH(in, out, RES_QUEUE_LEN)
                    583: 
                    584: struct Scsi_Host *irq2host[NR_IRQS];
                    585: 
                    586: static void    isp1020_enable_irqs(struct Scsi_Host *);
                    587: static void    isp1020_disable_irqs(struct Scsi_Host *);
                    588: static int     isp1020_init(struct Scsi_Host *);
                    589: static int     isp1020_reset_hardware(struct Scsi_Host *);
                    590: static int     isp1020_set_defaults(struct Scsi_Host *);
                    591: static int     isp1020_load_parameters(struct Scsi_Host *);
                    592: static int     isp1020_mbox_command(struct Scsi_Host *, u_short []); 
                    593: static int     isp1020_return_status(struct Status_Entry *);
                    594: static void    isp1020_intr_handler(int, void *, struct pt_regs *);
                    595: 
                    596: #if USE_NVRAM_DEFAULTS
                    597: static int     isp1020_get_defaults(struct Scsi_Host *);
                    598: static int     isp1020_verify_nvram(struct Scsi_Host *);
                    599: static u_short isp1020_read_nvram_word(struct Scsi_Host *, u_short);
                    600: #endif
                    601: 
                    602: #if DEBUG_ISP1020
                    603: static void    isp1020_print_scsi_cmd(Scsi_Cmnd *);
                    604: #endif
                    605: #if DEBUG_ISP1020_INTR
                    606: static void    isp1020_print_status_entry(struct Status_Entry *);
                    607: #endif
                    608: 
                    609: static struct proc_dir_entry proc_scsi_isp1020 = {
                    610:        PROC_SCSI_QLOGICISP, 7, "isp1020",
                    611:        S_IFDIR | S_IRUGO | S_IXUGO, 2
                    612: };
                    613: 
                    614: 
                    615: static inline void isp1020_enable_irqs(struct Scsi_Host *host)
                    616: {
                    617:        outw(ISP_EN_INT|ISP_EN_RISC, host->io_port + PCI_INTF_CTL);
                    618: }
                    619: 
                    620: 
                    621: static inline void isp1020_disable_irqs(struct Scsi_Host *host)
                    622: {
                    623:        outw(0x0, host->io_port + PCI_INTF_CTL);
                    624: }
                    625: 
                    626: 
                    627: int isp1020_detect(Scsi_Host_Template *tmpt)
                    628: {
                    629:        int hosts = 0;
                    630:        u_short index;
                    631:        u_char bus, device_fn;
                    632:        struct Scsi_Host *host;
                    633:        struct isp1020_hostdata *hostdata;
                    634: 
                    635:        ENTER("isp1020_detect");
                    636: 
                    637:        tmpt->proc_dir = &proc_scsi_isp1020;
                    638: 
                    639:        if (pcibios_present() == 0) {
                    640:                printk("qlogicisp : PCI bios not present\n");
                    641:                return 0;
                    642:        }
                    643: 
                    644:        memset(irq2host, 0, sizeof(irq2host));
                    645: 
                    646:        for (index = 0; pcibios_find_device(PCI_VENDOR_ID_QLOGIC,
                    647:                                            PCI_DEVICE_ID_QLOGIC_ISP1020,
                    648:                                            index, &bus, &device_fn) == 0;
                    649:             index++)
                    650:        {
                    651:                host = scsi_register(tmpt, sizeof(struct isp1020_hostdata));
                    652:                hostdata = (struct isp1020_hostdata *) host->hostdata;
                    653: 
                    654:                memset(hostdata, 0, sizeof(struct isp1020_hostdata));
                    655:                hostdata->bus = bus;
                    656:                hostdata->device_fn = device_fn;
                    657: 
                    658:                if (isp1020_init(host) || isp1020_reset_hardware(host)
                    659: #if USE_NVRAM_DEFAULTS
                    660:                    || isp1020_get_defaults(host)
                    661: #else
                    662:                    || isp1020_set_defaults(host)
                    663: #endif /* USE_NVRAM_DEFAULTS */
                    664:                    || isp1020_load_parameters(host)) {
                    665:                        scsi_unregister(host);
                    666:                        continue;
                    667:                }
                    668: 
                    669:                host->this_id = hostdata->host_param.initiator_scsi_id;
                    670: 
                    671:                if (request_irq(host->irq, isp1020_intr_handler, SA_INTERRUPT,
                    672:                                "qlogicisp", NULL))
                    673:                {
                    674:                        printk("qlogicisp : interrupt %d already in use\n",
                    675:                               host->irq);
                    676:                        scsi_unregister(host);
                    677:                        continue;
                    678:                }
                    679: 
                    680:                if (check_region(host->io_port, 0xff)) {
                    681:                        printk("qlogicisp : i/o region 0x%04x-0x%04x already "
                    682:                               "in use\n",
                    683:                               host->io_port, host->io_port + 0xff);
                    684:                        free_irq(host->irq, NULL);
                    685:                        scsi_unregister(host);
                    686:                        continue;
                    687:                }
                    688: 
                    689:                request_region(host->io_port, 0xff, "qlogicisp");
                    690:                irq2host[host->irq] = host;
                    691: 
                    692:                outw(0x0, host->io_port + PCI_SEMAPHORE);
                    693:                outw(HCCR_CLEAR_RISC_INTR, host->io_port + HOST_HCCR);
                    694:                isp1020_enable_irqs(host);
                    695: 
                    696:                hosts++;
                    697:        }
                    698: 
                    699:        LEAVE("isp1020_detect");
                    700: 
                    701:        return hosts;
                    702: }
                    703: 
                    704: 
                    705: int isp1020_release(struct Scsi_Host *host)
                    706: {
                    707:        struct isp1020_hostdata *hostdata;
                    708: 
                    709:        ENTER("isp1020_release");
                    710: 
                    711:        hostdata = (struct isp1020_hostdata *) host->hostdata;
                    712: 
                    713:        outw(0x0, host->io_port + PCI_INTF_CTL);
                    714:        free_irq(host->irq, NULL);
                    715: 
                    716:        release_region(host->io_port, 0xff);
                    717: 
                    718:        LEAVE("isp1020_release");
                    719: 
                    720:        return 0;
                    721: }
                    722: 
                    723: 
                    724: const char *isp1020_info(struct Scsi_Host *host)
                    725: {
                    726:        static char buf[80];
                    727:        struct isp1020_hostdata *hostdata;
                    728: 
                    729:        ENTER("isp1020_info");
                    730: 
                    731:        hostdata = (struct isp1020_hostdata *) host->hostdata;
                    732:        sprintf(buf,
                    733:                "QLogic ISP1020 SCSI on PCI bus %d device %d irq %d base 0x%x",
                    734:                hostdata->bus, (hostdata->device_fn & 0xf8) >> 3, host->irq,
                    735:                host->io_port);
                    736: 
                    737:        LEAVE("isp1020_info");
                    738: 
                    739:        return buf;
                    740: }
                    741: 
                    742: 
                    743: /*
                    744:  * The middle SCSI layer ensures that queuecommand never gets invoked
                    745:  * concurrently with itself or the interrupt handler (though the
                    746:  * interrupt handler may call this routine as part of
                    747:  * request-completion handling).
                    748:  */
                    749: int isp1020_queuecommand(Scsi_Cmnd *Cmnd, void (*done)(Scsi_Cmnd *))
                    750: {
                    751:        int i, sg_count, n, num_free;
                    752:        u_int in_ptr, out_ptr;
                    753:        struct dataseg * ds;
                    754:        struct scatterlist *sg;
                    755:        struct Command_Entry *cmd;
                    756:        struct Continuation_Entry *cont;
                    757:        struct Scsi_Host *host;
                    758:        struct isp1020_hostdata *hostdata;
                    759: 
                    760:        ENTER("isp1020_queuecommand");
                    761: 
                    762:        host = Cmnd->host;
                    763:        hostdata = (struct isp1020_hostdata *) host->hostdata;
                    764:        Cmnd->scsi_done = done;
                    765: 
                    766:        DEBUG(isp1020_print_scsi_cmd(Cmnd));
                    767: 
                    768:        out_ptr = inw(host->io_port + MBOX4);
                    769:        in_ptr  = hostdata->req_in_ptr;
                    770: 
                    771:        DEBUG(printk("qlogicisp : request queue depth %d\n",
                    772:                     REQ_QUEUE_DEPTH(in_ptr, out_ptr)));
                    773: 
                    774:        cmd = (struct Command_Entry *) &hostdata->req[in_ptr][0];
                    775:        in_ptr = (in_ptr + 1) & QLOGICISP_REQ_QUEUE_LEN;
                    776:        if (in_ptr == out_ptr) {
                    777:                printk("qlogicisp : request queue overflow\n");
                    778:                return 1;
                    779:        }
                    780: 
                    781:        if (hostdata->send_marker) {
                    782:                struct Marker_Entry *marker;
                    783: 
                    784:                TRACE("queue marker", in_ptr, 0);
                    785: 
                    786:                DEBUG(printk("qlogicisp : adding marker entry\n"));
                    787:                marker = (struct Marker_Entry *) cmd;
                    788:                memset(marker, 0, sizeof(struct Marker_Entry));
                    789: 
                    790:                marker->hdr.entry_type = ENTRY_MARKER;
                    791:                marker->hdr.entry_cnt = 1;
                    792:                marker->modifier = SYNC_ALL;
                    793: 
                    794:                hostdata->send_marker = 0;
                    795: 
                    796:                if (((in_ptr + 1) & QLOGICISP_REQ_QUEUE_LEN) == out_ptr) {
                    797:                        outw(in_ptr, host->io_port + MBOX4);
                    798:                        hostdata->req_in_ptr = in_ptr;
                    799:                        printk("qlogicisp : request queue overflow\n");
                    800:                        return 1;
                    801:                }
                    802:                cmd = (struct Command_Entry *) &hostdata->req[in_ptr][0];
                    803:                in_ptr = (in_ptr + 1) & QLOGICISP_REQ_QUEUE_LEN;
                    804:        }
                    805: 
                    806:        TRACE("queue command", in_ptr, Cmnd);
                    807: 
                    808:        memset(cmd, 0, sizeof(struct Command_Entry));
                    809: 
                    810:        cmd->hdr.entry_type = ENTRY_COMMAND;
                    811:        cmd->hdr.entry_cnt = 1;
                    812: 
                    813:        cmd->handle = (u_int) virt_to_bus(Cmnd);
                    814:        cmd->target_lun = Cmnd->lun;
                    815:        cmd->target_id = Cmnd->target;
                    816:        cmd->cdb_length = Cmnd->cmd_len;
                    817:        cmd->control_flags = CFLAG_READ | CFLAG_WRITE;
                    818:        cmd->time_out = 30;
                    819: 
                    820:        memcpy(cmd->cdb, Cmnd->cmnd, Cmnd->cmd_len);
                    821: 
                    822:        if (Cmnd->use_sg) {
                    823:                cmd->segment_cnt = sg_count = Cmnd->use_sg;
                    824:                sg = (struct scatterlist *) Cmnd->request_buffer;
                    825:                ds = cmd->dataseg;
                    826: 
                    827:                /* fill in first four sg entries: */
                    828:                n = sg_count;
                    829:                if (n > 4)
                    830:                        n = 4;
                    831:                for (i = 0; i < n; i++) {
                    832:                        ds[i].d_base  = (u_int) virt_to_bus(sg->address);
                    833:                        ds[i].d_count = sg->length;
                    834:                        ++sg;
                    835:                }
                    836:                sg_count -= 4;
                    837: 
                    838:                while (sg_count > 0) {
                    839:                        ++cmd->hdr.entry_cnt;
                    840:                        cont = (struct Continuation_Entry *)
                    841:                                &hostdata->req[in_ptr][0];
                    842:                        in_ptr = (in_ptr + 1) & QLOGICISP_REQ_QUEUE_LEN;
                    843:                        if (in_ptr == out_ptr) {
                    844:                                printk("isp1020: unexpected request queue "
                    845:                                       "overflow\n");
                    846:                                return 1;
                    847:                        }
                    848:                        TRACE("queue continuation", in_ptr, 0);
                    849:                        cont->hdr.entry_type = ENTRY_CONTINUATION;
                    850:                        cont->hdr.entry_cnt  = 0;
                    851:                        cont->hdr.sys_def_1  = 0;
                    852:                        cont->hdr.flags      = 0;
                    853:                        cont->reserved = 0;
                    854:                        ds = cont->dataseg;
                    855:                        n = sg_count;
                    856:                        if (n > 7)
                    857:                                n = 7;
                    858:                        for (i = 0; i < n; ++i) {
                    859:                                ds[i].d_base = (u_int)virt_to_bus(sg->address);
                    860:                                ds[i].d_count = sg->length;
                    861:                                ++sg;
                    862:                        }
                    863:                        sg_count -= n;
                    864:                }
                    865:        } else {
                    866:                cmd->dataseg[0].d_base =
                    867:                        (u_int) virt_to_bus(Cmnd->request_buffer);
                    868:                cmd->dataseg[0].d_count =
                    869:                        (u_int) Cmnd->request_bufflen;
                    870:                cmd->segment_cnt = 1;
                    871:        }
                    872: 
                    873:        outw(in_ptr, host->io_port + MBOX4);
                    874:        hostdata->req_in_ptr = in_ptr;
                    875: 
                    876:        num_free = QLOGICISP_REQ_QUEUE_LEN - REQ_QUEUE_DEPTH(in_ptr, out_ptr);
                    877:        host->can_queue = host->host_busy + num_free;
                    878:        host->sg_tablesize = QLOGICISP_MAX_SG(num_free);
                    879: 
                    880:        LEAVE("isp1020_queuecommand");
                    881: 
                    882:        return 0;
                    883: }
                    884: 
                    885: 
                    886: #define ASYNC_EVENT_INTERRUPT  0x01
                    887: 
                    888: void isp1020_intr_handler(int irq, void *dev_id, struct pt_regs *regs)
                    889: {
                    890:        Scsi_Cmnd *Cmnd;
                    891:        struct Status_Entry *sts;
                    892:        struct Scsi_Host *host;
                    893:        struct isp1020_hostdata *hostdata;
                    894:        u_int in_ptr, out_ptr;
                    895:        u_short status;
                    896: 
                    897:        ENTER_INTR("isp1020_intr_handler");
                    898: 
                    899:        host = irq2host[irq];
                    900:        if (!host) {
                    901:                printk("qlogicisp : unexpected interrupt on line %d\n", irq);
                    902:                return;
                    903:        }
                    904:        hostdata = (struct isp1020_hostdata *) host->hostdata;
                    905: 
                    906:        DEBUG_INTR(printk("qlogicisp : interrupt on line %d\n", irq));
                    907: 
                    908:        if (!(inw(host->io_port + PCI_INTF_STS) & 0x04)) {
                    909:                /* spurious interrupts can happen legally */
                    910:                DEBUG_INTR(printk("qlogicisp: got spurious interrupt\n"));
                    911:                return;
                    912:        }
                    913:        in_ptr = inw(host->io_port + MBOX5);
                    914:        outw(HCCR_CLEAR_RISC_INTR, host->io_port + HOST_HCCR);
                    915: 
                    916:        if ((inw(host->io_port + PCI_SEMAPHORE) & ASYNC_EVENT_INTERRUPT)) {
                    917:                status = inw(host->io_port + MBOX0);
                    918: 
                    919:                DEBUG_INTR(printk("qlogicisp : mbox completion status: %x\n",
                    920:                                  status));
                    921: 
                    922:                switch (status) {
                    923:                      case ASYNC_SCSI_BUS_RESET:
                    924:                      case EXECUTION_TIMEOUT_RESET:
                    925:                        hostdata->send_marker = 1;
                    926:                        break;
                    927:                      case INVALID_COMMAND:
                    928:                      case HOST_INTERFACE_ERROR:
                    929:                      case COMMAND_ERROR:
                    930:                      case COMMAND_PARAM_ERROR:
                    931:                        printk("qlogicisp : bad mailbox return status\n");
                    932:                        break;
                    933:                }
                    934:                outw(0x0, host->io_port + PCI_SEMAPHORE);
                    935:        }
                    936:        out_ptr = hostdata->res_out_ptr;
                    937: 
                    938:        DEBUG_INTR(printk("qlogicisp : response queue update\n"));
                    939:        DEBUG_INTR(printk("qlogicisp : response queue depth %d\n",
                    940:                          QUEUE_DEPTH(in_ptr, out_ptr)));
                    941: 
                    942:        while (out_ptr != in_ptr) {
                    943:                sts = (struct Status_Entry *) &hostdata->res[out_ptr][0];
                    944:                out_ptr = (out_ptr + 1) & RES_QUEUE_LEN;
                    945: 
                    946:                Cmnd = (Scsi_Cmnd *) bus_to_virt(sts->handle);
                    947: 
                    948:                TRACE("done", out_ptr, Cmnd);
                    949: 
                    950:                if (sts->completion_status == CS_RESET_OCCURRED
                    951:                    || sts->completion_status == CS_ABORTED
                    952:                    || (sts->status_flags & STF_BUS_RESET))
                    953:                        hostdata->send_marker = 1;
                    954: 
                    955:                if (sts->state_flags & SF_GOT_SENSE)
                    956:                        memcpy(Cmnd->sense_buffer, sts->req_sense_data,
                    957:                               sizeof(Cmnd->sense_buffer));
                    958: 
                    959:                DEBUG_INTR(isp1020_print_status_entry(sts));
                    960: 
                    961:                if (sts->hdr.entry_type == ENTRY_STATUS)
                    962:                        Cmnd->result = isp1020_return_status(sts);
                    963:                else
                    964:                        Cmnd->result = DID_ERROR << 16;
                    965: 
                    966:                outw(out_ptr, host->io_port + MBOX5);
                    967:                (*Cmnd->scsi_done)(Cmnd);
                    968:        }
                    969:        hostdata->res_out_ptr = out_ptr;
                    970: 
                    971:        LEAVE_INTR("isp1020_intr_handler");
                    972: }
                    973: 
                    974: 
                    975: static int isp1020_return_status(struct Status_Entry *sts)
                    976: {
                    977:        int host_status = DID_ERROR;
                    978: #if DEBUG_ISP1020_INTR
                    979:        static char *reason[] = {
                    980:                "DID_OK",
                    981:                "DID_NO_CONNECT",
                    982:                "DID_BUS_BUSY",
                    983:                "DID_TIME_OUT",
                    984:                "DID_BAD_TARGET",
                    985:                "DID_ABORT",
                    986:                "DID_PARITY",
                    987:                "DID_ERROR",
                    988:                "DID_RESET",
                    989:                "DID_BAD_INTR"
                    990:        };
                    991: #endif /* DEBUG_ISP1020_INTR */
                    992: 
                    993:        ENTER("isp1020_return_status");
                    994: 
                    995:        DEBUG(printk("qlogicisp : completion status = 0x%04x\n",
                    996:                     sts->completion_status));
                    997: 
                    998:        switch(sts->completion_status) {
                    999:              case CS_COMPLETE:
                   1000:                host_status = DID_OK;
                   1001:                break;
                   1002:              case CS_INCOMPLETE:
                   1003:                if (!(sts->state_flags & SF_GOT_BUS))
                   1004:                        host_status = DID_NO_CONNECT;
                   1005:                else if (!(sts->state_flags & SF_GOT_TARGET))
                   1006:                        host_status = DID_BAD_TARGET;
                   1007:                else if (!(sts->state_flags & SF_SENT_CDB))
                   1008:                        host_status = DID_ERROR;
                   1009:                else if (!(sts->state_flags & SF_TRANSFERRED_DATA))
                   1010:                        host_status = DID_ERROR;
                   1011:                else if (!(sts->state_flags & SF_GOT_STATUS))
                   1012:                        host_status = DID_ERROR;
                   1013:                else if (!(sts->state_flags & SF_GOT_SENSE))
                   1014:                        host_status = DID_ERROR;
                   1015:                break;
                   1016:              case CS_DMA_ERROR:
                   1017:              case CS_TRANSPORT_ERROR:
                   1018:                host_status = DID_ERROR;
                   1019:                break;
                   1020:              case CS_RESET_OCCURRED:
                   1021:                host_status = DID_RESET;
                   1022:                break;
                   1023:              case CS_ABORTED:
                   1024:                host_status = DID_ABORT;
                   1025:                break;
                   1026:              case CS_TIMEOUT:
                   1027:                host_status = DID_TIME_OUT;
                   1028:                break;
                   1029:              case CS_DATA_OVERRUN:
                   1030:              case CS_COMMAND_OVERRUN:
                   1031:              case CS_STATUS_OVERRUN:
                   1032:              case CS_BAD_MESSAGE:
                   1033:              case CS_NO_MESSAGE_OUT:
                   1034:              case CS_EXT_ID_FAILED:
                   1035:              case CS_IDE_MSG_FAILED:
                   1036:              case CS_ABORT_MSG_FAILED:
                   1037:              case CS_NOP_MSG_FAILED:
                   1038:              case CS_PARITY_ERROR_MSG_FAILED:
                   1039:              case CS_DEVICE_RESET_MSG_FAILED:
                   1040:              case CS_ID_MSG_FAILED:
                   1041:              case CS_UNEXP_BUS_FREE:
                   1042:              case CS_INVALID_ENTRY_TYPE:
                   1043:              case CS_DEVICE_QUEUE_FULL:
                   1044:              case CS_SCSI_PHASE_SKIPPED:
                   1045:              case CS_ARS_FAILED:
                   1046:                host_status = DID_ERROR;
                   1047:                break;
                   1048:              case CS_DATA_UNDERRUN:
                   1049:                host_status = DID_OK;
                   1050:                break;
                   1051:              default:
                   1052:                printk("qlogicisp : unknown completion status 0x%04x\n",
                   1053:                       sts->completion_status);
                   1054:                host_status = DID_ERROR;
                   1055:                break;
                   1056:        }
                   1057: 
                   1058:        DEBUG_INTR(printk("qlogicisp : host status (%s) scsi status %x\n",
                   1059:                          reason[host_status], sts->scsi_status));
                   1060: 
                   1061:        LEAVE("isp1020_return_status");
                   1062: 
                   1063:        return (sts->scsi_status & STATUS_MASK) | (host_status << 16);
                   1064: }
                   1065: 
                   1066: 
                   1067: int isp1020_abort(Scsi_Cmnd *Cmnd)
                   1068: {
                   1069:        u_short param[6];
                   1070:        struct Scsi_Host *host;
                   1071:        struct isp1020_hostdata *hostdata;
                   1072:        int return_status = SCSI_ABORT_SUCCESS;
                   1073:        u_int cmdaddr = virt_to_bus(Cmnd);
                   1074: 
                   1075:        ENTER("isp1020_abort");
                   1076: 
                   1077:        host = Cmnd->host;
                   1078:        hostdata = (struct isp1020_hostdata *) host->hostdata;
                   1079: 
                   1080:        isp1020_disable_irqs(host);
                   1081: 
                   1082:        param[0] = MBOX_ABORT;
                   1083:        param[1] = (((u_short) Cmnd->target) << 8) | Cmnd->lun;
                   1084:        param[2] = cmdaddr >> 16;
                   1085:        param[3] = cmdaddr & 0xffff;
                   1086: 
                   1087:        isp1020_mbox_command(host, param);
                   1088: 
                   1089:        if (param[0] != MBOX_COMMAND_COMPLETE) {
                   1090:                printk("qlogicisp : scsi abort failure: %x\n", param[0]);
                   1091:                return_status = SCSI_ABORT_ERROR;
                   1092:        }
                   1093: 
                   1094:        isp1020_enable_irqs(host);
                   1095: 
                   1096:        LEAVE("isp1020_abort");
                   1097: 
                   1098:        return return_status;
                   1099: }
                   1100: 
                   1101: 
                   1102: int isp1020_reset(Scsi_Cmnd *Cmnd, unsigned int reset_flags)
                   1103: {
                   1104:        u_short param[6];
                   1105:        struct Scsi_Host *host;
                   1106:        struct isp1020_hostdata *hostdata;
                   1107:        int return_status = SCSI_RESET_SUCCESS;
                   1108: 
                   1109:        ENTER("isp1020_reset");
                   1110: 
                   1111:        host = Cmnd->host;
                   1112:        hostdata = (struct isp1020_hostdata *) host->hostdata;
                   1113: 
                   1114:        param[0] = MBOX_BUS_RESET;
                   1115:        param[1] = hostdata->host_param.bus_reset_delay;
                   1116: 
                   1117:        isp1020_disable_irqs(host);
                   1118: 
                   1119:        isp1020_mbox_command(host, param);
                   1120: 
                   1121:        if (param[0] != MBOX_COMMAND_COMPLETE) {
                   1122:                printk("qlogicisp : scsi bus reset failure: %x\n", param[0]);
                   1123:                return_status = SCSI_RESET_ERROR;
                   1124:        }
                   1125: 
                   1126:        isp1020_enable_irqs(host);
                   1127: 
                   1128:        LEAVE("isp1020_reset");
                   1129: 
                   1130:        return return_status;;
                   1131: }
                   1132: 
                   1133: 
                   1134: int isp1020_biosparam(Disk *disk, kdev_t n, int ip[])
                   1135: {
                   1136:        int size = disk->capacity;
                   1137: 
                   1138:        ENTER("isp1020_biosparam");
                   1139: 
                   1140:        ip[0] = 64;
                   1141:        ip[1] = 32;
                   1142:        ip[2] = size >> 11;
                   1143:        if (ip[2] > 1024) {
                   1144:                ip[0] = 255;
                   1145:                ip[1] = 63;
                   1146:                ip[2] = size / (ip[0] * ip[1]);
                   1147:                if (ip[2] > 1023)
                   1148:                        ip[2] = 1023;
                   1149:        }
                   1150: 
                   1151:        LEAVE("isp1020_biosparam");
                   1152: 
                   1153:        return 0;
                   1154: }
                   1155: 
                   1156: 
                   1157: static int isp1020_reset_hardware(struct Scsi_Host *host)
                   1158: {
                   1159:        u_short param[6];
                   1160:        int loop_count;
                   1161: 
                   1162:        ENTER("isp1020_reset_hardware");
                   1163: 
                   1164:        outw(ISP_RESET, host->io_port + PCI_INTF_CTL);
                   1165:        outw(HCCR_RESET, host->io_port + HOST_HCCR);
                   1166:        outw(HCCR_RELEASE, host->io_port + HOST_HCCR);
                   1167:        outw(HCCR_BIOS_DISABLE, host->io_port + HOST_HCCR);
                   1168: 
                   1169:        loop_count = DEFAULT_LOOP_COUNT;
                   1170:        while (--loop_count && inw(host->io_port + HOST_HCCR) == RISC_BUSY)
                   1171:                barrier();
                   1172:        if (!loop_count)
                   1173:                printk("qlogicisp: reset_hardware loop timeout\n");
                   1174: 
                   1175:        outw(0, host->io_port + ISP_CFG1);
                   1176: 
                   1177: #if DEBUG_ISP1020
                   1178:        printk("qlogicisp : mbox 0 0x%04x \n", inw(host->io_port + MBOX0));
                   1179:        printk("qlogicisp : mbox 1 0x%04x \n", inw(host->io_port + MBOX1));
                   1180:        printk("qlogicisp : mbox 2 0x%04x \n", inw(host->io_port + MBOX2));
                   1181:        printk("qlogicisp : mbox 3 0x%04x \n", inw(host->io_port + MBOX3));
                   1182:        printk("qlogicisp : mbox 4 0x%04x \n", inw(host->io_port + MBOX4));
                   1183:        printk("qlogicisp : mbox 5 0x%04x \n", inw(host->io_port + MBOX5));
                   1184: #endif /* DEBUG_ISP1020 */
                   1185: 
                   1186:        DEBUG(printk("qlogicisp : loading risc ram\n"));
                   1187: 
                   1188: #if RELOAD_FIRMWARE
                   1189:        {
                   1190:                int i;
                   1191:                for (i = 0; i < risc_code_length01; i++) {
                   1192:                        param[0] = MBOX_WRITE_RAM_WORD;
                   1193:                        param[1] = risc_code_addr01 + i;
                   1194:                        param[2] = risc_code01[i];
                   1195: 
                   1196:                        isp1020_mbox_command(host, param);
                   1197: 
                   1198:                        if (param[0] != MBOX_COMMAND_COMPLETE) {
                   1199:                                printk("qlogicisp : firmware load failure\n");
                   1200:                                return 1;
                   1201:                        }
                   1202:                }
                   1203:        }
                   1204: #endif /* RELOAD_FIRMWARE */
                   1205: 
                   1206:        DEBUG(printk("qlogicisp : verifying checksum\n"));
                   1207: 
                   1208:        param[0] = MBOX_VERIFY_CHECKSUM;
                   1209:        param[1] = risc_code_addr01;
                   1210: 
                   1211:        isp1020_mbox_command(host, param);
                   1212: 
                   1213:        if (param[0] != MBOX_COMMAND_COMPLETE) {
                   1214:                printk("qlogicisp : ram checksum failure\n");
                   1215:                return 1;
                   1216:        }
                   1217: 
                   1218:        DEBUG(printk("qlogicisp : executing firmware\n"));
                   1219: 
                   1220:        param[0] = MBOX_EXEC_FIRMWARE;
                   1221:        param[1] = risc_code_addr01;
                   1222: 
                   1223:        isp1020_mbox_command(host, param);
                   1224: 
                   1225:        param[0] = MBOX_ABOUT_FIRMWARE;
                   1226: 
                   1227:        isp1020_mbox_command(host, param);
                   1228: 
                   1229:        if (param[0] != MBOX_COMMAND_COMPLETE) {
                   1230:                printk("qlogicisp : about firmware failure\n");
                   1231:                return 1;
                   1232:        }
                   1233: 
                   1234:        DEBUG(printk("qlogicisp : firmware major revision %d\n", param[1]));
                   1235:        DEBUG(printk("qlogicisp : firmware minor revision %d\n", param[2]));
                   1236: 
                   1237:        LEAVE("isp1020_reset_hardware");
                   1238: 
                   1239:        return 0;
                   1240: }
                   1241: 
                   1242: 
                   1243: static int isp1020_init(struct Scsi_Host *sh)
                   1244: {
                   1245:        u_int io_base;
                   1246:        struct isp1020_hostdata *hostdata;
                   1247:        u_char bus, device_fn, revision, irq;
                   1248:        u_short vendor_id, device_id, command;
                   1249: 
                   1250:        ENTER("isp1020_init");
                   1251: 
                   1252:        hostdata = (struct isp1020_hostdata *) sh->hostdata;
                   1253:        bus = hostdata->bus;
                   1254:        device_fn = hostdata->device_fn;
                   1255: 
                   1256:        if (pcibios_read_config_word(bus, device_fn, PCI_VENDOR_ID, &vendor_id)
                   1257:             || pcibios_read_config_word(bus, device_fn,
                   1258:                                        PCI_DEVICE_ID, &device_id)
                   1259:             || pcibios_read_config_word(bus, device_fn,
                   1260:                                        PCI_COMMAND, &command)
                   1261:             || pcibios_read_config_dword(bus, device_fn,
                   1262:                                         PCI_BASE_ADDRESS_0, &io_base)
                   1263:            || pcibios_read_config_byte(bus, device_fn,
                   1264:                                        PCI_CLASS_REVISION, &revision)
                   1265:             || pcibios_read_config_byte(bus, device_fn,
                   1266:                                        PCI_INTERRUPT_LINE, &irq))
                   1267:        {
                   1268:                printk("qlogicisp : error reading PCI configuration\n");
                   1269:                return 1;
                   1270:        }
                   1271: 
                   1272:        if (vendor_id != PCI_VENDOR_ID_QLOGIC) {
                   1273:                printk("qlogicisp : 0x%04x is not QLogic vendor ID\n",
                   1274:                       vendor_id);
                   1275:                return 1;
                   1276:        }
                   1277: 
                   1278:        if (device_id != PCI_DEVICE_ID_QLOGIC_ISP1020) {
                   1279:                printk("qlogicisp : 0x%04x does not match ISP1020 device id\n",
                   1280:                       device_id);
                   1281:                return 1;
                   1282:        }
                   1283: 
                   1284:        if (command & PCI_COMMAND_IO && (io_base & 3) == 1)
                   1285:                io_base &= PCI_BASE_ADDRESS_IO_MASK;
                   1286:        else {
                   1287:                printk("qlogicisp : i/o mapping is disabled\n");
                   1288:                return 1;
                   1289:        }
                   1290: 
                   1291:        if (!(command & PCI_COMMAND_MASTER)) {
                   1292:                printk("qlogicisp : bus mastering is disabled\n");
                   1293:                return 1;
                   1294:        }
                   1295: 
                   1296:        if (revision != ISP1020_REV_ID)
                   1297:                printk("qlogicisp : new isp1020 revision ID (%d)\n", revision);
                   1298: 
                   1299:        if (inw(io_base + PCI_ID_LOW) != PCI_VENDOR_ID_QLOGIC
                   1300:            || inw(io_base + PCI_ID_HIGH) != PCI_DEVICE_ID_QLOGIC_ISP1020)
                   1301:        {
                   1302:                printk("qlogicisp : can't decode i/o address space at 0x%x\n",
                   1303:                       io_base);
                   1304:                return 1;
                   1305:        }
                   1306: 
                   1307:        hostdata->revision = revision;
                   1308: 
                   1309:        sh->irq = irq;
                   1310:        sh->io_port = io_base;
                   1311: 
                   1312:        LEAVE("isp1020_init");
                   1313: 
                   1314:        return 0;
                   1315: }
                   1316: 
                   1317: 
                   1318: #if USE_NVRAM_DEFAULTS
                   1319: 
                   1320: static int isp1020_get_defaults(struct Scsi_Host *host)
                   1321: {
                   1322:        int i;
                   1323:        u_short value;
                   1324:        struct isp1020_hostdata *hostdata =
                   1325:                (struct isp1020_hostdata *) host->hostdata;
                   1326: 
                   1327:        ENTER("isp1020_get_defaults");
                   1328: 
                   1329:        if (!isp1020_verify_nvram(host)) {
                   1330:                printk("qlogicisp : nvram checksum failure\n");
                   1331:                printk("qlogicisp : attempting to use default parameters\n");
                   1332:                return isp1020_set_defaults(host);
                   1333:        }
                   1334: 
                   1335:        value = isp1020_read_nvram_word(host, 2);
                   1336:        hostdata->host_param.fifo_threshold = (value >> 8) & 0x03;
                   1337:        hostdata->host_param.host_adapter_enable = (value >> 11) & 0x01;
                   1338:        hostdata->host_param.initiator_scsi_id = (value >> 12) & 0x0f;
                   1339: 
                   1340:        value = isp1020_read_nvram_word(host, 3);
                   1341:        hostdata->host_param.bus_reset_delay = value & 0xff;
                   1342:        hostdata->host_param.retry_count = value >> 8;
                   1343: 
                   1344:        value = isp1020_read_nvram_word(host, 4);
                   1345:        hostdata->host_param.retry_delay = value & 0xff;
                   1346:        hostdata->host_param.async_data_setup_time = (value >> 8) & 0x0f;
                   1347:        hostdata->host_param.req_ack_active_negation = (value >> 12) & 0x01;
                   1348:        hostdata->host_param.data_line_active_negation = (value >> 13) & 0x01;
                   1349:        hostdata->host_param.data_dma_burst_enable = (value >> 14) & 0x01;
                   1350:        hostdata->host_param.command_dma_burst_enable = (value >> 15);
                   1351: 
                   1352:        value = isp1020_read_nvram_word(host, 5);
                   1353:        hostdata->host_param.tag_aging = value & 0xff;
                   1354: 
                   1355:        value = isp1020_read_nvram_word(host, 6);
                   1356:        hostdata->host_param.selection_timeout = value & 0xffff;
                   1357: 
                   1358:        value = isp1020_read_nvram_word(host, 7);
                   1359:        hostdata->host_param.max_queue_depth = value & 0xffff;
                   1360: 
                   1361: #if DEBUG_ISP1020_SETUP
                   1362:        printk("qlogicisp : fifo threshold=%d\n",
                   1363:               hostdata->host_param.fifo_threshold);
                   1364:        printk("qlogicisp : initiator scsi id=%d\n",
                   1365:               hostdata->host_param.initiator_scsi_id);
                   1366:        printk("qlogicisp : bus reset delay=%d\n",
                   1367:               hostdata->host_param.bus_reset_delay);
                   1368:        printk("qlogicisp : retry count=%d\n",
                   1369:               hostdata->host_param.retry_count);
                   1370:        printk("qlogicisp : retry delay=%d\n",
                   1371:               hostdata->host_param.retry_delay);
                   1372:        printk("qlogicisp : async data setup time=%d\n",
                   1373:               hostdata->host_param.async_data_setup_time);
                   1374:        printk("qlogicisp : req/ack active negation=%d\n",
                   1375:               hostdata->host_param.req_ack_active_negation);
                   1376:        printk("qlogicisp : data line active negation=%d\n",
                   1377:               hostdata->host_param.data_line_active_negation);
                   1378:        printk("qlogicisp : data DMA burst enable=%d\n",
                   1379:               hostdata->host_param.data_dma_burst_enable);
                   1380:        printk("qlogicisp : command DMA burst enable=%d\n",
                   1381:               hostdata->host_param.command_dma_burst_enable);
                   1382:        printk("qlogicisp : tag age limit=%d\n",
                   1383:               hostdata->host_param.tag_aging);
                   1384:        printk("qlogicisp : selection timeout limit=%d\n",
                   1385:               hostdata->host_param.selection_timeout);
                   1386:        printk("qlogicisp : max queue depth=%d\n",
                   1387:               hostdata->host_param.max_queue_depth);
                   1388: #endif /* DEBUG_ISP1020_SETUP */
                   1389: 
                   1390:        for (i = 0; i < MAX_TARGETS; i++) {
                   1391: 
                   1392:                value = isp1020_read_nvram_word(host, 14 + i * 3);
                   1393:                hostdata->dev_param[i].device_flags = value & 0xff;
                   1394:                hostdata->dev_param[i].execution_throttle = value >> 8;
                   1395: 
                   1396:                value = isp1020_read_nvram_word(host, 15 + i * 3);
                   1397:                hostdata->dev_param[i].synchronous_period = value & 0xff;
                   1398:                hostdata->dev_param[i].synchronous_offset = (value >> 8) & 0x0f;
                   1399:                hostdata->dev_param[i].device_enable = (value >> 12) & 0x01;
                   1400: 
                   1401: #if DEBUG_ISP1020_SETUP
                   1402:                printk("qlogicisp : target 0x%02x\n", i);
                   1403:                printk("qlogicisp :     device flags=0x%02x\n",
                   1404:                       hostdata->dev_param[i].device_flags);
                   1405:                printk("qlogicisp :     execution throttle=%d\n",
                   1406:                       hostdata->dev_param[i].execution_throttle);
                   1407:                printk("qlogicisp :     synchronous period=%d\n",
                   1408:                       hostdata->dev_param[i].synchronous_period);
                   1409:                printk("qlogicisp :     synchronous offset=%d\n",
                   1410:                       hostdata->dev_param[i].synchronous_offset);
                   1411:                printk("qlogicisp :     device enable=%d\n",
                   1412:                       hostdata->dev_param[i].device_enable);
                   1413: #endif /* DEBUG_ISP1020_SETUP */
                   1414:        }
                   1415: 
                   1416:        LEAVE("isp1020_get_defaults");
                   1417: 
                   1418:        return 0;
                   1419: }
                   1420: 
                   1421: 
                   1422: #define ISP1020_NVRAM_LEN      0x40
                   1423: #define ISP1020_NVRAM_SIG1     0x5349
                   1424: #define ISP1020_NVRAM_SIG2     0x2050
                   1425: 
                   1426: static int isp1020_verify_nvram(struct Scsi_Host *host)
                   1427: {
                   1428:        int     i;
                   1429:        u_short value;
                   1430:        u_char checksum = 0;
                   1431: 
                   1432:        for (i = 0; i < ISP1020_NVRAM_LEN; i++) {
                   1433:                value = isp1020_read_nvram_word(host, i);
                   1434: 
                   1435:                switch (i) {
                   1436:                      case 0:
                   1437:                        if (value != ISP1020_NVRAM_SIG1) return 0;
                   1438:                        break;
                   1439:                      case 1:
                   1440:                        if (value != ISP1020_NVRAM_SIG2) return 0;
                   1441:                        break;
                   1442:                      case 2:
                   1443:                        if ((value & 0xff) != 0x02) return 0;
                   1444:                        break;
                   1445:                }
                   1446:                checksum += value & 0xff;
                   1447:                checksum += value >> 8;
                   1448:        }
                   1449: 
                   1450:        return (checksum == 0);
                   1451: }
                   1452: 
                   1453: #define NVRAM_DELAY() udelay(2) /* 2 microsecond delay */
                   1454: 
                   1455: 
                   1456: u_short isp1020_read_nvram_word(struct Scsi_Host *host, u_short byte)
                   1457: {
                   1458:        int i;
                   1459:        u_short value, output, input;
                   1460: 
                   1461:        byte &= 0x3f; byte |= 0x0180;
                   1462: 
                   1463:        for (i = 8; i >= 0; i--) {
                   1464:                output = ((byte >> i) & 0x1) ? 0x4 : 0x0;
                   1465:                outw(output | 0x2, host->io_port + PCI_NVRAM); NVRAM_DELAY();
                   1466:                outw(output | 0x3, host->io_port + PCI_NVRAM); NVRAM_DELAY();
                   1467:                outw(output | 0x2, host->io_port + PCI_NVRAM); NVRAM_DELAY();
                   1468:        }
                   1469: 
                   1470:        for (i = 0xf, value = 0; i >= 0; i--) {
                   1471:                value <<= 1;
                   1472:                outw(0x3, host->io_port + PCI_NVRAM); NVRAM_DELAY();
                   1473:                input = inw(host->io_port + PCI_NVRAM); NVRAM_DELAY();
                   1474:                outw(0x2, host->io_port + PCI_NVRAM); NVRAM_DELAY();
                   1475:                if (input & 0x8) value |= 1;
                   1476:        }
                   1477: 
                   1478:        outw(0x0, host->io_port + PCI_NVRAM); NVRAM_DELAY();
                   1479: 
                   1480:        return value;
                   1481: }
                   1482: 
                   1483: #endif /* USE_NVRAM_DEFAULTS */
                   1484: 
                   1485: 
                   1486: static int isp1020_set_defaults(struct Scsi_Host *host)
                   1487: {
                   1488:        struct isp1020_hostdata *hostdata =
                   1489:                (struct isp1020_hostdata *) host->hostdata;
                   1490:        int i;
                   1491: 
                   1492:        ENTER("isp1020_set_defaults");
                   1493: 
                   1494:        hostdata->host_param.fifo_threshold = 2;
                   1495:        hostdata->host_param.host_adapter_enable = 1;
                   1496:        hostdata->host_param.initiator_scsi_id = 7;
                   1497:        hostdata->host_param.bus_reset_delay = 3;
                   1498:        hostdata->host_param.retry_count = 0;
                   1499:        hostdata->host_param.retry_delay = 1;
                   1500:        hostdata->host_param.async_data_setup_time = 6;
                   1501:        hostdata->host_param.req_ack_active_negation = 1;
                   1502:        hostdata->host_param.data_line_active_negation = 1;
                   1503:        hostdata->host_param.data_dma_burst_enable = 1;
                   1504:        hostdata->host_param.command_dma_burst_enable = 1;
                   1505:        hostdata->host_param.tag_aging = 8;
                   1506:        hostdata->host_param.selection_timeout = 250;
                   1507:        hostdata->host_param.max_queue_depth = 256;
                   1508: 
                   1509:        for (i = 0; i < MAX_TARGETS; i++) {
                   1510:                hostdata->dev_param[i].device_flags = 0xfd;
                   1511:                hostdata->dev_param[i].execution_throttle = 16;
                   1512:                hostdata->dev_param[i].synchronous_period = 25;
                   1513:                hostdata->dev_param[i].synchronous_offset = 12;
                   1514:                hostdata->dev_param[i].device_enable = 1;
                   1515:        }
                   1516: 
                   1517:        LEAVE("isp1020_set_defaults");
                   1518: 
                   1519:        return 0;
                   1520: }
                   1521: 
                   1522: 
                   1523: static int isp1020_load_parameters(struct Scsi_Host *host)
                   1524: {
                   1525:        int i, k;
                   1526:        u_int queue_addr;
                   1527:        u_short param[6];
                   1528:        u_short isp_cfg1;
                   1529:        unsigned long flags;
                   1530:        struct isp1020_hostdata *hostdata =
                   1531:                (struct isp1020_hostdata *) host->hostdata;
                   1532: 
                   1533:        ENTER("isp1020_load_parameters");
                   1534: 
                   1535:        save_flags(flags);
                   1536:        cli();
                   1537: 
                   1538:        outw(hostdata->host_param.fifo_threshold, host->io_port + ISP_CFG1);
                   1539: 
                   1540:        param[0] = MBOX_SET_INIT_SCSI_ID;
                   1541:        param[1] = hostdata->host_param.initiator_scsi_id;
                   1542: 
                   1543:        isp1020_mbox_command(host, param);
                   1544: 
                   1545:        if (param[0] != MBOX_COMMAND_COMPLETE) {
                   1546:                restore_flags(flags);
                   1547:                printk("qlogicisp : set initiator id failure\n");
                   1548:                return 1;
                   1549:        }
                   1550: 
                   1551:        param[0] = MBOX_SET_RETRY_COUNT;
                   1552:        param[1] = hostdata->host_param.retry_count;
                   1553:        param[2] = hostdata->host_param.retry_delay;
                   1554: 
                   1555:        isp1020_mbox_command(host, param);
                   1556: 
                   1557:        if (param[0] != MBOX_COMMAND_COMPLETE) {
                   1558:                restore_flags(flags);
                   1559:                printk("qlogicisp : set retry count failure\n");
                   1560:                return 1;
                   1561:        }
                   1562: 
                   1563:        param[0] = MBOX_SET_ASYNC_DATA_SETUP_TIME;
                   1564:        param[1] = hostdata->host_param.async_data_setup_time;
                   1565: 
                   1566:        isp1020_mbox_command(host, param);
                   1567: 
                   1568:        if (param[0] != MBOX_COMMAND_COMPLETE) {
                   1569:                restore_flags(flags);
                   1570:                printk("qlogicisp : async data setup time failure\n");
                   1571:                return 1;
                   1572:        }
                   1573: 
                   1574:        param[0] = MBOX_SET_ACTIVE_NEG_STATE;
                   1575:        param[1] = (hostdata->host_param.req_ack_active_negation << 4)
                   1576:                | (hostdata->host_param.data_line_active_negation << 5);
                   1577: 
                   1578:        isp1020_mbox_command(host, param);
                   1579: 
                   1580:        if (param[0] != MBOX_COMMAND_COMPLETE) {
                   1581:                restore_flags(flags);
                   1582:                printk("qlogicisp : set active negation state failure\n");
                   1583:                return 1;
                   1584:        }
                   1585: 
                   1586:        param[0] = MBOX_SET_PCI_CONTROL_PARAMS;
                   1587:        param[1] = hostdata->host_param.data_dma_burst_enable << 1;
                   1588:        param[2] = hostdata->host_param.command_dma_burst_enable << 1;
                   1589: 
                   1590:        isp1020_mbox_command(host, param);
                   1591: 
                   1592:        if (param[0] != MBOX_COMMAND_COMPLETE) {
                   1593:                restore_flags(flags);
                   1594:                printk("qlogicisp : set pci control parameter failure\n");
                   1595:                return 1;
                   1596:        }
                   1597: 
                   1598:        isp_cfg1 = inw(host->io_port + ISP_CFG1);
                   1599: 
                   1600:        if (hostdata->host_param.data_dma_burst_enable 
                   1601:             || hostdata->host_param.command_dma_burst_enable)
                   1602:                isp_cfg1 |= 0x0004;
                   1603:        else
                   1604:                isp_cfg1 &= 0xfffb;
                   1605: 
                   1606:        outw(isp_cfg1, host->io_port + ISP_CFG1);
                   1607: 
                   1608:        param[0] = MBOX_SET_TAG_AGE_LIMIT;
                   1609:        param[1] = hostdata->host_param.tag_aging;
                   1610: 
                   1611:        isp1020_mbox_command(host, param);
                   1612: 
                   1613:        if (param[0] != MBOX_COMMAND_COMPLETE) {
                   1614:                restore_flags(flags);
                   1615:                printk("qlogicisp : set tag age limit failure\n");
                   1616:                return 1;
                   1617:        }
                   1618: 
                   1619:        param[0] = MBOX_SET_SELECT_TIMEOUT;
                   1620:        param[1] = hostdata->host_param.selection_timeout;
                   1621: 
                   1622:        isp1020_mbox_command(host, param);
                   1623: 
                   1624:        if (param[0] != MBOX_COMMAND_COMPLETE) {
                   1625:                restore_flags(flags);
                   1626:                printk("qlogicisp : set selection timeout failure\n");
                   1627:                return 1;
                   1628:        }
                   1629: 
                   1630:        for (i = 0; i < MAX_TARGETS; i++) {
                   1631: 
                   1632:                if (!hostdata->dev_param[i].device_enable)
                   1633:                        continue;
                   1634: 
                   1635:                param[0] = MBOX_SET_TARGET_PARAMS;
                   1636:                param[1] = i << 8;
                   1637:                param[2] = hostdata->dev_param[i].device_flags << 8;
                   1638:                param[3] = (hostdata->dev_param[i].synchronous_offset << 8)
                   1639:                        | hostdata->dev_param[i].synchronous_period;
                   1640: 
                   1641:                isp1020_mbox_command(host, param);
                   1642: 
                   1643:                if (param[0] != MBOX_COMMAND_COMPLETE) {
                   1644:                        restore_flags(flags);
                   1645:                        printk("qlogicisp : set target parameter failure\n");
                   1646:                        return 1;
                   1647:                }
                   1648: 
                   1649:                for (k = 0; k < MAX_LUNS; k++) {
                   1650: 
                   1651:                        param[0] = MBOX_SET_DEV_QUEUE_PARAMS;
                   1652:                        param[1] = (i << 8) | k;
                   1653:                        param[2] = hostdata->host_param.max_queue_depth;
                   1654:                        param[3] = hostdata->dev_param[i].execution_throttle;
                   1655: 
                   1656:                        isp1020_mbox_command(host, param);
                   1657: 
                   1658:                        if (param[0] != MBOX_COMMAND_COMPLETE) {
                   1659:                                restore_flags(flags);
                   1660:                                printk("qlogicisp : set device queue "
                   1661:                                       "parameter failure\n");
                   1662:                                return 1;
                   1663:                        }
                   1664:                }
                   1665:        }
                   1666: 
                   1667:        queue_addr = (u_int) virt_to_bus(&hostdata->res[0][0]);
                   1668: 
                   1669:        param[0] = MBOX_INIT_RES_QUEUE;
                   1670:        param[1] = RES_QUEUE_LEN + 1;
                   1671:        param[2] = (u_short) (queue_addr >> 16);
                   1672:        param[3] = (u_short) (queue_addr & 0xffff);
                   1673:        param[4] = 0;
                   1674:        param[5] = 0;
                   1675: 
                   1676:        isp1020_mbox_command(host, param);
                   1677: 
                   1678:        if (param[0] != MBOX_COMMAND_COMPLETE) {
                   1679:                restore_flags(flags);
                   1680:                printk("qlogicisp : set response queue failure\n");
                   1681:                return 1;
                   1682:        }
                   1683: 
                   1684:        queue_addr = (u_int) virt_to_bus(&hostdata->req[0][0]);
                   1685: 
                   1686:        param[0] = MBOX_INIT_REQ_QUEUE;
                   1687:        param[1] = QLOGICISP_REQ_QUEUE_LEN + 1;
                   1688:        param[2] = (u_short) (queue_addr >> 16);
                   1689:        param[3] = (u_short) (queue_addr & 0xffff);
                   1690:        param[4] = 0;
                   1691: 
                   1692:        isp1020_mbox_command(host, param);
                   1693: 
                   1694:        if (param[0] != MBOX_COMMAND_COMPLETE) {
                   1695:                restore_flags(flags);
                   1696:                printk("qlogicisp : set request queue failure\n");
                   1697:                return 1;
                   1698:        }
                   1699: 
                   1700:        restore_flags(flags);
                   1701: 
                   1702:        LEAVE("isp1020_load_parameters");
                   1703: 
                   1704:        return 0;
                   1705: }
                   1706: 
                   1707: 
                   1708: /*
                   1709:  * currently, this is only called during initialization or abort/reset,
                   1710:  * at which times interrupts are disabled, so polling is OK, I guess...
                   1711:  */
                   1712: static int isp1020_mbox_command(struct Scsi_Host *host, u_short param[])
                   1713: {
                   1714:        int loop_count;
                   1715: 
                   1716:        if (mbox_param[param[0]] == 0)
                   1717:                return 1;
                   1718: 
                   1719:        loop_count = DEFAULT_LOOP_COUNT;
                   1720:        while (--loop_count && inw(host->io_port + HOST_HCCR) & 0x0080)
                   1721:                barrier();
                   1722:        if (!loop_count)
                   1723:                printk("qlogicisp: mbox_command loop timeout #1\n");
                   1724: 
                   1725:        switch(mbox_param[param[0]] >> 4) {
                   1726:              case 6: outw(param[5], host->io_port + MBOX5);
                   1727:              case 5: outw(param[4], host->io_port + MBOX4);
                   1728:              case 4: outw(param[3], host->io_port + MBOX3);
                   1729:              case 3: outw(param[2], host->io_port + MBOX2);
                   1730:              case 2: outw(param[1], host->io_port + MBOX1);
                   1731:              case 1: outw(param[0], host->io_port + MBOX0);
                   1732:        }
                   1733: 
                   1734:        outw(0x0, host->io_port + PCI_SEMAPHORE);
                   1735:        outw(HCCR_CLEAR_RISC_INTR, host->io_port + HOST_HCCR);
                   1736:        outw(HCCR_SET_HOST_INTR, host->io_port + HOST_HCCR);
                   1737: 
                   1738:        loop_count = DEFAULT_LOOP_COUNT;
                   1739:        while (--loop_count && !(inw(host->io_port + PCI_INTF_STS) & 0x04))
                   1740:                barrier();
                   1741:        if (!loop_count)
                   1742:                printk("qlogicisp: mbox_command loop timeout #2\n");
                   1743: 
                   1744:        loop_count = DEFAULT_LOOP_COUNT;
                   1745:        while (--loop_count && inw(host->io_port + MBOX0) == 0x04)
                   1746:                barrier();
                   1747:        if (!loop_count)
                   1748:                printk("qlogicisp: mbox_command loop timeout #3\n");
                   1749: 
                   1750:        switch(mbox_param[param[0]] & 0xf) {
                   1751:              case 6: param[5] = inw(host->io_port + MBOX5);
                   1752:              case 5: param[4] = inw(host->io_port + MBOX4);
                   1753:              case 4: param[3] = inw(host->io_port + MBOX3);
                   1754:              case 3: param[2] = inw(host->io_port + MBOX2);
                   1755:              case 2: param[1] = inw(host->io_port + MBOX1);
                   1756:              case 1: param[0] = inw(host->io_port + MBOX0);
                   1757:        }
                   1758: 
                   1759:        outw(0x0, host->io_port + PCI_SEMAPHORE);
                   1760:        outw(HCCR_CLEAR_RISC_INTR, host->io_port + HOST_HCCR);
                   1761: 
                   1762:        return 0;
                   1763: }
                   1764: 
                   1765: 
                   1766: #if DEBUG_ISP1020_INTR
                   1767: 
                   1768: void isp1020_print_status_entry(struct Status_Entry *status)
                   1769: {
                   1770:        int i;
                   1771: 
                   1772:        printk("qlogicisp : entry count = 0x%02x, type = 0x%02x, flags = 0x%02x\n",
                   1773:               status->hdr.entry_cnt, status->hdr.entry_type, status->hdr.flags);
                   1774:        printk("qlogicisp : scsi status = 0x%04x, completion status = 0x%04x\n",
                   1775:               status->scsi_status, status->completion_status);
                   1776:        printk("qlogicisp : state flags = 0x%04x, status flags = 0x%04x\n",
                   1777:               status->state_flags, status->status_flags);
                   1778:        printk("qlogicisp : time = 0x%04x, request sense length = 0x%04x\n",
                   1779:               status->time, status->req_sense_len);
                   1780:        printk("qlogicisp : residual transfer length = 0x%08x\n", status->residual);
                   1781: 
                   1782:        for (i = 0; i < status->req_sense_len; i++)
                   1783:                printk("qlogicisp : sense data = 0x%02x\n", status->req_sense_data[i]);
                   1784: }
                   1785: 
                   1786: #endif /* DEBUG_ISP1020_INTR */
                   1787: 
                   1788: 
                   1789: #if DEBUG_ISP1020
                   1790: 
                   1791: void isp1020_print_scsi_cmd(Scsi_Cmnd *cmd)
                   1792: {
                   1793:        int i;
                   1794: 
                   1795:        printk("qlogicisp : target = 0x%02x, lun = 0x%02x, cmd_len = 0x%02x\n",
                   1796:               cmd->target, cmd->lun, cmd->cmd_len);
                   1797:        printk("qlogicisp : command = ");
                   1798:        for (i = 0; i < cmd->cmd_len; i++)
                   1799:                printk("0x%02x ", cmd->cmnd[i]);
                   1800:        printk("\n");
                   1801: }
                   1802: 
                   1803: #endif /* DEBUG_ISP1020 */
                   1804: 
                   1805: 
                   1806: #ifdef MODULE
                   1807: Scsi_Host_Template driver_template = QLOGICISP;
                   1808: 
                   1809: #include "scsi_module.c"
                   1810: #endif /* MODULE */

unix.superglobalmegacorp.com

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