|
|
1.1 ! root 1: /* ! 2: * in2000.h - Linux device driver definitions for the ! 3: * Always IN2000 ISA SCSI card. ! 4: * ! 5: * IMPORTANT: This file is for version 1.33 - 26/Aug/1998 ! 6: * ! 7: * Copyright (c) 1996 John Shifflett, GeoLog Consulting ! 8: * [email protected] ! 9: * [email protected] ! 10: * ! 11: * This program is free software; you can redistribute it and/or modify ! 12: * it under the terms of the GNU General Public License as published by ! 13: * the Free Software Foundation; either version 2, or (at your option) ! 14: * any later version. ! 15: * ! 16: * This program is distributed in the hope that it will be useful, ! 17: * but WITHOUT ANY WARRANTY; without even the implied warranty of ! 18: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ! 19: * GNU General Public License for more details. ! 20: * ! 21: */ ! 22: ! 23: #ifndef IN2000_H ! 24: #define IN2000_H ! 25: ! 26: #include <asm/io.h> ! 27: ! 28: #define PROC_INTERFACE /* add code for /proc/scsi/in2000/xxx interface */ ! 29: #ifdef PROC_INTERFACE ! 30: #define PROC_STATISTICS /* add code for keeping various real time stats */ ! 31: #endif ! 32: ! 33: #define SYNC_DEBUG /* extra info on sync negotiation printed */ ! 34: #define DEBUGGING_ON /* enable command-line debugging bitmask */ ! 35: #define DEBUG_DEFAULTS 0 /* default bitmask - change from command-line */ ! 36: ! 37: #define FAST_READ_IO /* No problems with these on my machine */ ! 38: #define FAST_WRITE_IO ! 39: ! 40: #ifdef DEBUGGING_ON ! 41: #define DB(f,a) if (hostdata->args & (f)) a; ! 42: #define CHECK_NULL(p,s) /* if (!(p)) {printk("\n"); while (1) printk("NP:%s\r",(s));} */ ! 43: #else ! 44: #define DB(f,a) ! 45: #define CHECK_NULL(p,s) ! 46: #endif ! 47: ! 48: #define uchar unsigned char ! 49: ! 50: #define read1_io(a) (inb(hostdata->io_base+(a))) ! 51: #define read2_io(a) (inw(hostdata->io_base+(a))) ! 52: #define write1_io(b,a) (outb((b),hostdata->io_base+(a))) ! 53: #define write2_io(w,a) (outw((w),hostdata->io_base+(a))) ! 54: ! 55: /* These inline assembly defines are derived from a patch ! 56: * sent to me by Bill Earnest. He's done a lot of very ! 57: * valuable thinking, testing, and coding during his effort ! 58: * to squeeze more speed out of this driver. I really think ! 59: * that we are doing IO at close to the maximum now with ! 60: * the fifo. (And yes, insw uses 'edi' while outsw uses ! 61: * 'esi'. Thanks Bill!) ! 62: */ ! 63: ! 64: #define FAST_READ2_IO() \ ! 65: __asm__ __volatile__ ("\n \ ! 66: cld \n \ ! 67: orl %%ecx, %%ecx \n \ ! 68: jz 1f \n \ ! 69: rep \n \ ! 70: insw %%dx \n \ ! 71: 1: " \ ! 72: : "=D" (sp) /* output */ \ ! 73: : "d" (f), "D" (sp), "c" (i) /* input */ \ ! 74: : "edx", "ecx", "edi" ) /* trashed */ ! 75: ! 76: #define FAST_WRITE2_IO() \ ! 77: __asm__ __volatile__ ("\n \ ! 78: cld \n \ ! 79: orl %%ecx, %%ecx \n \ ! 80: jz 1f \n \ ! 81: rep \n \ ! 82: outsw %%dx \n \ ! 83: 1: " \ ! 84: : "=S" (sp) /* output */ \ ! 85: : "d" (f), "S" (sp), "c" (i) /* input */ \ ! 86: : "edx", "ecx", "esi" ) /* trashed */ ! 87: ! 88: ! 89: /* IN2000 io_port offsets */ ! 90: #define IO_WD_ASR 0x00 /* R - 3393 auxstat reg */ ! 91: #define ASR_INT 0x80 ! 92: #define ASR_LCI 0x40 ! 93: #define ASR_BSY 0x20 ! 94: #define ASR_CIP 0x10 ! 95: #define ASR_PE 0x02 ! 96: #define ASR_DBR 0x01 ! 97: #define IO_WD_ADDR 0x00 /* W - 3393 address reg */ ! 98: #define IO_WD_DATA 0x01 /* R/W - rest of 3393 regs */ ! 99: #define IO_FIFO 0x02 /* R/W - in2000 dual-port fifo (16 bits) */ ! 100: #define IN2000_FIFO_SIZE 2048 /* fifo capacity in bytes */ ! 101: #define IO_CARD_RESET 0x03 /* W - in2000 start master reset */ ! 102: #define IO_FIFO_COUNT 0x04 /* R - in2000 fifo counter */ ! 103: #define IO_FIFO_WRITE 0x05 /* W - clear fifo counter, start write */ ! 104: #define IO_FIFO_READ 0x07 /* W - start fifo read */ ! 105: #define IO_LED_OFF 0x08 /* W - turn off in2000 activity LED */ ! 106: #define IO_SWITCHES 0x08 /* R - read in2000 dip switch */ ! 107: #define SW_ADDR0 0x01 /* bit 0 = bit 0 of index to io addr */ ! 108: #define SW_ADDR1 0x02 /* bit 1 = bit 1 of index io addr */ ! 109: #define SW_DISINT 0x04 /* bit 2 true if ints disabled */ ! 110: #define SW_INT0 0x08 /* bit 3 = bit 0 of index to interrupt */ ! 111: #define SW_INT1 0x10 /* bit 4 = bit 1 of index to interrupt */ ! 112: #define SW_INT_SHIFT 3 /* shift right this amount to right justify int bits */ ! 113: #define SW_SYNC_DOS5 0x20 /* bit 5 used by Always BIOS */ ! 114: #define SW_FLOPPY 0x40 /* bit 6 true if floppy enabled */ ! 115: #define SW_BIT7 0x80 /* bit 7 hardwired true (ground) */ ! 116: #define IO_LED_ON 0x09 /* W - turn on in2000 activity LED */ ! 117: #define IO_HARDWARE 0x0a /* R - read in2000 hardware rev, stop reset */ ! 118: #define IO_INTR_MASK 0x0c /* W - in2000 interrupt mask reg */ ! 119: #define IMASK_WD 0x01 /* WD33c93 interrupt mask */ ! 120: #define IMASK_FIFO 0x02 /* FIFO interrupt mask */ ! 121: ! 122: /* wd register names */ ! 123: #define WD_OWN_ID 0x00 ! 124: #define WD_CONTROL 0x01 ! 125: #define WD_TIMEOUT_PERIOD 0x02 ! 126: #define WD_CDB_1 0x03 ! 127: #define WD_CDB_2 0x04 ! 128: #define WD_CDB_3 0x05 ! 129: #define WD_CDB_4 0x06 ! 130: #define WD_CDB_5 0x07 ! 131: #define WD_CDB_6 0x08 ! 132: #define WD_CDB_7 0x09 ! 133: #define WD_CDB_8 0x0a ! 134: #define WD_CDB_9 0x0b ! 135: #define WD_CDB_10 0x0c ! 136: #define WD_CDB_11 0x0d ! 137: #define WD_CDB_12 0x0e ! 138: #define WD_TARGET_LUN 0x0f ! 139: #define WD_COMMAND_PHASE 0x10 ! 140: #define WD_SYNCHRONOUS_TRANSFER 0x11 ! 141: #define WD_TRANSFER_COUNT_MSB 0x12 ! 142: #define WD_TRANSFER_COUNT 0x13 ! 143: #define WD_TRANSFER_COUNT_LSB 0x14 ! 144: #define WD_DESTINATION_ID 0x15 ! 145: #define WD_SOURCE_ID 0x16 ! 146: #define WD_SCSI_STATUS 0x17 ! 147: #define WD_COMMAND 0x18 ! 148: #define WD_DATA 0x19 ! 149: #define WD_QUEUE_TAG 0x1a ! 150: #define WD_AUXILIARY_STATUS 0x1f ! 151: ! 152: /* WD commands */ ! 153: #define WD_CMD_RESET 0x00 ! 154: #define WD_CMD_ABORT 0x01 ! 155: #define WD_CMD_ASSERT_ATN 0x02 ! 156: #define WD_CMD_NEGATE_ACK 0x03 ! 157: #define WD_CMD_DISCONNECT 0x04 ! 158: #define WD_CMD_RESELECT 0x05 ! 159: #define WD_CMD_SEL_ATN 0x06 ! 160: #define WD_CMD_SEL 0x07 ! 161: #define WD_CMD_SEL_ATN_XFER 0x08 ! 162: #define WD_CMD_SEL_XFER 0x09 ! 163: #define WD_CMD_RESEL_RECEIVE 0x0a ! 164: #define WD_CMD_RESEL_SEND 0x0b ! 165: #define WD_CMD_WAIT_SEL_RECEIVE 0x0c ! 166: #define WD_CMD_TRANS_ADDR 0x18 ! 167: #define WD_CMD_TRANS_INFO 0x20 ! 168: #define WD_CMD_TRANSFER_PAD 0x21 ! 169: #define WD_CMD_SBT_MODE 0x80 ! 170: ! 171: /* SCSI Bus Phases */ ! 172: #define PHS_DATA_OUT 0x00 ! 173: #define PHS_DATA_IN 0x01 ! 174: #define PHS_COMMAND 0x02 ! 175: #define PHS_STATUS 0x03 ! 176: #define PHS_MESS_OUT 0x06 ! 177: #define PHS_MESS_IN 0x07 ! 178: ! 179: /* Command Status Register definitions */ ! 180: ! 181: /* reset state interrupts */ ! 182: #define CSR_RESET 0x00 ! 183: #define CSR_RESET_AF 0x01 ! 184: ! 185: /* successful completion interrupts */ ! 186: #define CSR_RESELECT 0x10 ! 187: #define CSR_SELECT 0x11 ! 188: #define CSR_SEL_XFER_DONE 0x16 ! 189: #define CSR_XFER_DONE 0x18 ! 190: ! 191: /* paused or aborted interrupts */ ! 192: #define CSR_MSGIN 0x20 ! 193: #define CSR_SDP 0x21 ! 194: #define CSR_SEL_ABORT 0x22 ! 195: #define CSR_RESEL_ABORT 0x25 ! 196: #define CSR_RESEL_ABORT_AM 0x27 ! 197: #define CSR_ABORT 0x28 ! 198: ! 199: /* terminated interrupts */ ! 200: #define CSR_INVALID 0x40 ! 201: #define CSR_UNEXP_DISC 0x41 ! 202: #define CSR_TIMEOUT 0x42 ! 203: #define CSR_PARITY 0x43 ! 204: #define CSR_PARITY_ATN 0x44 ! 205: #define CSR_BAD_STATUS 0x45 ! 206: #define CSR_UNEXP 0x48 ! 207: ! 208: /* service required interrupts */ ! 209: #define CSR_RESEL 0x80 ! 210: #define CSR_RESEL_AM 0x81 ! 211: #define CSR_DISC 0x85 ! 212: #define CSR_SRV_REQ 0x88 ! 213: ! 214: /* Own ID/CDB Size register */ ! 215: #define OWNID_EAF 0x08 ! 216: #define OWNID_EHP 0x10 ! 217: #define OWNID_RAF 0x20 ! 218: #define OWNID_FS_8 0x00 ! 219: #define OWNID_FS_12 0x40 ! 220: #define OWNID_FS_16 0x80 ! 221: ! 222: /* Control register */ ! 223: #define CTRL_HSP 0x01 ! 224: #define CTRL_HA 0x02 ! 225: #define CTRL_IDI 0x04 ! 226: #define CTRL_EDI 0x08 ! 227: #define CTRL_HHP 0x10 ! 228: #define CTRL_POLLED 0x00 ! 229: #define CTRL_BURST 0x20 ! 230: #define CTRL_BUS 0x40 ! 231: #define CTRL_DMA 0x80 ! 232: ! 233: /* Timeout Period register */ ! 234: #define TIMEOUT_PERIOD_VALUE 20 /* results in 200 ms. */ ! 235: ! 236: /* Synchronous Transfer Register */ ! 237: #define STR_FSS 0x80 ! 238: ! 239: /* Destination ID register */ ! 240: #define DSTID_DPD 0x40 ! 241: #define DATA_OUT_DIR 0 ! 242: #define DATA_IN_DIR 1 ! 243: #define DSTID_SCC 0x80 ! 244: ! 245: /* Source ID register */ ! 246: #define SRCID_MASK 0x07 ! 247: #define SRCID_SIV 0x08 ! 248: #define SRCID_DSP 0x20 ! 249: #define SRCID_ES 0x40 ! 250: #define SRCID_ER 0x80 ! 251: ! 252: ! 253: ! 254: #define ILLEGAL_STATUS_BYTE 0xff ! 255: ! 256: ! 257: #define DEFAULT_SX_PER 500 /* (ns) fairly safe */ ! 258: #define DEFAULT_SX_OFF 0 /* aka async */ ! 259: ! 260: #define OPTIMUM_SX_PER 252 /* (ns) best we can do (mult-of-4) */ ! 261: #define OPTIMUM_SX_OFF 12 /* size of in2000 fifo */ ! 262: ! 263: struct sx_period { ! 264: unsigned int period_ns; ! 265: uchar reg_value; ! 266: }; ! 267: ! 268: ! 269: struct IN2000_hostdata { ! 270: struct Scsi_Host *next; ! 271: uchar chip; /* what kind of wd33c93 chip? */ ! 272: uchar microcode; /* microcode rev if 'B' */ ! 273: unsigned short io_base; /* IO port base */ ! 274: unsigned int dip_switch; /* dip switch settings */ ! 275: unsigned int hrev; /* hardware revision of card */ ! 276: volatile uchar busy[8]; /* index = target, bit = lun */ ! 277: volatile Scsi_Cmnd *input_Q; /* commands waiting to be started */ ! 278: volatile Scsi_Cmnd *selecting; /* trying to select this command */ ! 279: volatile Scsi_Cmnd *connected; /* currently connected command */ ! 280: volatile Scsi_Cmnd *disconnected_Q;/* commands waiting for reconnect */ ! 281: uchar state; /* what we are currently doing */ ! 282: uchar fifo; /* what the FIFO is up to */ ! 283: uchar level2; /* extent to which Level-2 commands are used */ ! 284: uchar disconnect; /* disconnect/reselect policy */ ! 285: unsigned int args; /* set from command-line argument */ ! 286: uchar incoming_msg[8]; /* filled during message_in phase */ ! 287: int incoming_ptr; /* mainly used with EXTENDED messages */ ! 288: uchar outgoing_msg[8]; /* send this during next message_out */ ! 289: int outgoing_len; /* length of outgoing message */ ! 290: unsigned int default_sx_per; /* default transfer period for SCSI bus */ ! 291: uchar sync_xfer[8]; /* sync_xfer reg settings per target */ ! 292: uchar sync_stat[8]; /* status of sync negotiation per target */ ! 293: uchar sync_off; /* bit mask: don't use sync with these targets */ ! 294: #ifdef PROC_INTERFACE ! 295: uchar proc; /* bit mask: what's in proc output */ ! 296: #ifdef PROC_STATISTICS ! 297: unsigned long cmd_cnt[8]; /* # of commands issued per target */ ! 298: unsigned long int_cnt; /* # of interrupts serviced */ ! 299: unsigned long disc_allowed_cnt[8]; /* # of disconnects allowed per target */ ! 300: unsigned long disc_done_cnt[8]; /* # of disconnects done per target*/ ! 301: #endif ! 302: #endif ! 303: }; ! 304: ! 305: ! 306: /* defines for hostdata->chip */ ! 307: ! 308: #define C_WD33C93 0 ! 309: #define C_WD33C93A 1 ! 310: #define C_WD33C93B 2 ! 311: #define C_UNKNOWN_CHIP 100 ! 312: ! 313: /* defines for hostdata->state */ ! 314: ! 315: #define S_UNCONNECTED 0 ! 316: #define S_SELECTING 1 ! 317: #define S_RUNNING_LEVEL2 2 ! 318: #define S_CONNECTED 3 ! 319: #define S_PRE_TMP_DISC 4 ! 320: #define S_PRE_CMP_DISC 5 ! 321: ! 322: /* defines for hostdata->fifo */ ! 323: ! 324: #define FI_FIFO_UNUSED 0 ! 325: #define FI_FIFO_READING 1 ! 326: #define FI_FIFO_WRITING 2 ! 327: ! 328: /* defines for hostdata->level2 */ ! 329: /* NOTE: only the first 3 are trustworthy at this point - ! 330: * having trouble when more than 1 device is reading/writing ! 331: * at the same time... ! 332: */ ! 333: ! 334: #define L2_NONE 0 /* no combination commands - we get lots of ints */ ! 335: #define L2_SELECT 1 /* start with SEL_ATN_XFER, but never resume it */ ! 336: #define L2_BASIC 2 /* resume after STATUS ints & RDP messages */ ! 337: #define L2_DATA 3 /* resume after DATA_IN/OUT ints */ ! 338: #define L2_MOST 4 /* resume after anything except a RESELECT int */ ! 339: #define L2_RESELECT 5 /* resume after everything, including RESELECT ints */ ! 340: #define L2_ALL 6 /* always resume */ ! 341: ! 342: /* defines for hostdata->disconnect */ ! 343: ! 344: #define DIS_NEVER 0 ! 345: #define DIS_ADAPTIVE 1 ! 346: #define DIS_ALWAYS 2 ! 347: ! 348: /* defines for hostdata->args */ ! 349: ! 350: #define DB_TEST 1<<0 ! 351: #define DB_FIFO 1<<1 ! 352: #define DB_QUEUE_COMMAND 1<<2 ! 353: #define DB_EXECUTE 1<<3 ! 354: #define DB_INTR 1<<4 ! 355: #define DB_TRANSFER 1<<5 ! 356: #define DB_MASK 0x3f ! 357: ! 358: #define A_NO_SCSI_RESET 1<<15 ! 359: ! 360: ! 361: /* defines for hostdata->sync_xfer[] */ ! 362: ! 363: #define SS_UNSET 0 ! 364: #define SS_FIRST 1 ! 365: #define SS_WAITING 2 ! 366: #define SS_SET 3 ! 367: ! 368: /* defines for hostdata->proc */ ! 369: ! 370: #define PR_VERSION 1<<0 ! 371: #define PR_INFO 1<<1 ! 372: #define PR_STATISTICS 1<<2 ! 373: #define PR_CONNECTED 1<<3 ! 374: #define PR_INPUTQ 1<<4 ! 375: #define PR_DISCQ 1<<5 ! 376: #define PR_TEST 1<<6 ! 377: #define PR_STOP 1<<7 ! 378: ! 379: ! 380: #include <linux/version.h> ! 381: ! 382: #if LINUX_VERSION_CODE < 0x020100 /* 2.0.xx */ ! 383: # define in2000__INITFUNC(function) function ! 384: # define in2000__INIT ! 385: # define in2000__INITDATA ! 386: # define CLISPIN_LOCK(flags) do { save_flags(flags); cli(); } while(0) ! 387: # define CLISPIN_UNLOCK(flags) restore_flags(flags) ! 388: #else /* 2.1.xxx */ ! 389: # include <linux/init.h> ! 390: # include <asm/spinlock.h> ! 391: # define in2000__INITFUNC(function) __initfunc(function) ! 392: # define in2000__INIT __init ! 393: # define in2000__INITDATA __initdata ! 394: # define CLISPIN_LOCK(flags) spin_lock_irqsave(&io_request_lock, flags) ! 395: # define CLISPIN_UNLOCK(flags) spin_unlock_irqrestore(&io_request_lock, flags) ! 396: #endif ! 397: ! 398: ! 399: int in2000_detect(Scsi_Host_Template *) in2000__INIT; ! 400: int in2000_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); ! 401: int in2000_abort(Scsi_Cmnd *); ! 402: void in2000_setup(char *, int *) in2000__INIT; ! 403: int in2000_proc_info(char *, char **, off_t, int, int, int); ! 404: struct proc_dir_entry proc_scsi_in2000; ! 405: int in2000_biosparam(struct scsi_disk *, kdev_t, int *); ! 406: int in2000_reset(Scsi_Cmnd *, unsigned int); ! 407: ! 408: ! 409: #define IN2000_CAN_Q 16 ! 410: #define IN2000_SG SG_ALL ! 411: #define IN2000_CPL 2 ! 412: #define IN2000_HOST_ID 7 ! 413: ! 414: #if LINUX_VERSION_CODE < 0x020100 /* 2.0.xx */ ! 415: ! 416: #define IN2000 { NULL, /* link pointer for modules */ \ ! 417: NULL, /* usage_count for modules */ \ ! 418: &proc_scsi_in2000, /* pointer to /proc/scsi directory entry */ \ ! 419: in2000_proc_info, /* pointer to proc info function */ \ ! 420: "Always IN2000", /* device name */ \ ! 421: in2000_detect, /* returns number of in2000's found */ \ ! 422: NULL, /* optional unload function for modules */ \ ! 423: NULL, /* optional misc info function */ \ ! 424: NULL, /* send scsi command, wait for completion */ \ ! 425: in2000_queuecommand, /* queue scsi command, don't wait */ \ ! 426: in2000_abort, /* abort current command */ \ ! 427: in2000_reset, /* reset scsi bus */ \ ! 428: NULL, /* slave_attach - unused */ \ ! 429: in2000_biosparam, /* figures out BIOS parameters for lilo, etc */ \ ! 430: IN2000_CAN_Q, /* max commands we can queue up */ \ ! 431: IN2000_HOST_ID, /* host-adapter scsi id */ \ ! 432: IN2000_SG, /* scatter-gather table size */ \ ! 433: IN2000_CPL, /* commands per lun */ \ ! 434: 0, /* board counter */ \ ! 435: 0, /* unchecked dma */ \ ! 436: DISABLE_CLUSTERING \ ! 437: } ! 438: ! 439: #else /* 2.1.xxx */ ! 440: ! 441: #define IN2000 { proc_dir: &proc_scsi_in2000, /* pointer to /proc/scsi directory entry */ \ ! 442: proc_info: in2000_proc_info, /* pointer to proc info function */ \ ! 443: name: "Always IN2000", /* device name */ \ ! 444: detect: in2000_detect, /* returns number of in2000's found */ \ ! 445: queuecommand: in2000_queuecommand, /* queue scsi command, don't wait */ \ ! 446: abort: in2000_abort, /* abort current command */ \ ! 447: reset: in2000_reset, /* reset scsi bus */ \ ! 448: bios_param: in2000_biosparam, /* figures out BIOS parameters for lilo, etc */ \ ! 449: can_queue: IN2000_CAN_Q, /* max commands we can queue up */ \ ! 450: this_id: IN2000_HOST_ID, /* host-adapter scsi id */ \ ! 451: sg_tablesize: IN2000_SG, /* scatter-gather table size */ \ ! 452: cmd_per_lun: IN2000_CPL, /* commands per lun */ \ ! 453: use_clustering: DISABLE_CLUSTERING, /* ENABLE_CLUSTERING may speed things up */ \ ! 454: use_new_eh_code: 0 /* new error code - not using it yet */ \ ! 455: } ! 456: ! 457: #endif ! 458: ! 459: ! 460: #endif /* IN2000_H */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.