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

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

unix.superglobalmegacorp.com

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