#ifndef _WD7000_H /* $Id: $ * * Header file for the WD-7000 driver for Linux * * $Log: $ * Revision 1.1 1992/07/24 06:27:38 root * Initial revision * * Revision 1.1 1992/07/05 08:32:32 root * Initial revision * * Revision 1.1 1992/05/15 18:38:05 root * Initial revision * * Revision 1.1 1992/04/02 03:23:13 drew * Initial revision * * Revision 1.3 1992/01/27 14:46:29 tthorn * *** empty log message *** * */ #include #undef STATMASK #undef CONTROL #define IO_BASE 0x350 #define IRQ_LVL 15 #define DMA_CH 6 #define OGMB_CNT 8 #define ICMB_CNT 16 /* I/O Port interface 4.2 */ /* READ */ #define ASC_STAT IO_BASE #define INT_IM 0x80 /* Interrupt Image Flag */ #define CMD_RDY 0x40 /* Command Port Ready */ #define CMD_REJ 0x20 /* Command Port Byte Rejected */ #define ASC_INI 0x10 /* ASC Initialized Flag */ #define STATMASK 0xf0 /* The lower 4 Bytes are reserved */ /* This register serves two purposes * Diagnostics error code * Interrupt Status */ #define INTR_STAT ASC_STAT+1 #define ANYINTR 0x80 /* Mailbox Service possible/required */ #define IMB 0x40 /* 1 Incoming / 0 Outgoing */ #define MBMASK 0x3f /* if MSb is zero, the lower bits are diagnostic status * * Diagnostics: * 01 No diagnostic error occurred * 02 RAM failure * 03 FIFO R/W failed * 04 SBIC register read/write failed * 05 Initialization D-FF failed * 06 Host IRQ D-FF failed * 07 ROM checksum error * Interrupt status (bitwise): * 10NNNNNN outgoing mailbox NNNNNN is free * 11NNNNNN incoming mailbox NNNNNN needs service */ /* WRITE */ #define COMMAND ASC_STAT /* * COMMAND opcodes */ #define NO_OP 0 #define INITIALIZATION 1 /* initialization after reset (10 bytes) */ #define DISABLE_UNS_INTR 2 /* disable unsolicited interrupts */ #define ENABLE_UNS_INTR 3 /* enable unsolicited interrupts */ #define INTR_ON_FREE_OGMB 4 /* interrupt on free OGMB */ #define SCSI_SOFT_RESET 5 /* SCSI soft reset */ #define SCSI_HARD_RESET 6 /* SCSI hard reset acknowledge */ #define START_OGMB 0x80 /* start command in OGMB (n) */ #define SCAN_OGMBS 0xc0 /* start multiple commands, signature (n) */ /* where (n) = lower 6 bits */ /* * For INITIALIZATION: */ #define BUS_ON 48 /* x 125ns, 48 = 6000ns, BIOS uses 8000ns */ #define BUS_OFF 24 /* x 125ns, 24 = 3000ns, BIOS uses 1875ns */ #define INTR_ACK ASC_STAT+1 #define CONTROL ASC_STAT+2 #define INT_EN 0x08 /* Interrupt Enable */ #define DMA_EN 0x04 /* DMA Enable */ #define SCSI_RES 0x02 /* SCSI Reset */ #define ASC_RES 0x01 /* ASC Reset */ /* Mailbox Definition */ struct wd_mailbox{ unchar status; unchar scbptr[3]; }; /* These belong in scsi.h also */ #undef any2scsi #define any2scsi(up, p) \ (up)[0] = (((long)(p)) >> 16); \ (up)[1] = ((long)(p)) >> 8; \ (up)[2] = ((long)(p)); #define scsi2int(up) ( (((long)*(up)) << 16) + (((long)(up)[1]) << 8) + ((long)(up)[2]) ) #define xany2scsi(up, p) \ (up)[0] = ((long)(p)) >> 24; \ (up)[1] = ((long)(p)) >> 16; \ (up)[2] = ((long)(p)) >> 8; \ (up)[3] = ((long)(p)); #define xscsi2int(up) ( (((long)(up)[0]) << 24) + (((long)(up)[1]) << 16) \ + (((long)(up)[2]) << 8) + ((long)(up)[3]) ) #define MAX_CDB 12 #define MAX_SENSE 14 typedef struct scb { /* Command Control Block 5.4.1 */ unchar op; /* Command Control Block Operation Code */ unchar idlun; /* op=0,2:Target Id, op=1:Initiator Id */ /* Outbound data transfer, length is checked*/ /* Inbound data transfer, length is checked */ /* Logical Unit Number */ unchar cdb[12]; /* SCSI Command Block */ unchar status; /* SCSI Return Status */ unchar vue; /* Vendor Unique Error Code */ unchar maxlen[3]; /* Maximum Data Transfer Length */ unchar dataptr[3]; /* SCSI Data Block Pointer */ unchar linkptr[3]; /* Next Command Link Pointer */ unchar direc; /* Transfer Direction */ unchar reserved2[6]; /* SCSI Command Descriptor Block */ /* end of hardware SCB */ Scsi_Cmnd *SCpnt; /* Scsi_Cmnd using this SCB */ struct scb *next; /* for lists of scbs */ } Scb; /* * WD7000-specific scatter/gather element structure */ typedef struct sgb { unchar len[3]; unchar ptr[3]; } Sgb; /* * Note: MAX_SCBS _must_ be defined large enough to keep ahead of the * demand for SCBs, which will be at most WD7000_Q * WD7000_SG. 1 is * added to each because they can be 0. */ #define MAX_SCBS ((WD7000_Q+1) * (WD7000_SG+1)) /* * The driver is written to allow host-only commands to be executed. These * use a 16-byte block called an ICB. * * (Currently, only wd7000_info uses this, to get the firmware rev. level.) */ #define ICB_STATUS 16 /* set to icmb status by wd7000_intr_handle */ #define ICB_PHASE 17 /* set to 0 by wd7000_intr_handle */ #define ICB_LEN 18 /* actually 16; this includes the above */ int wd7000_detect(int); int wd7000_command(Scsi_Cmnd *); int wd7000_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); int wd7000_abort(Scsi_Cmnd *, int); const char *wd7000_info(void); int wd7000_reset(Scsi_Cmnd *); int wd7000_biosparam(int, int, int*); #ifndef NULL #define NULL 0 #endif /* * Define WD7000_SG to be the number of Sgbs that will fit in a block of * size WD7000_SCRIBBLE. WD7000_SCRIBBLE must be 512, 1024, 2048, or 4096. * * The sg_tablesize value will default to SG_NONE for older boards (before * rev 7.0), but will be changed to WD7000_SG when a newer board is * detected. */ #define WD7000_SCRIBBLE 512 #define WD7000_Q OGMB_CNT #define WD7000_SG (WD7000_SCRIBBLE / sizeof(Sgb)) #define WD7000 {\ "Western Digital WD-7000", \ wd7000_detect, \ wd7000_info, wd7000_command, \ wd7000_queuecommand, \ wd7000_abort, \ wd7000_reset, \ NULL, \ wd7000_biosparam, \ WD7000_Q, 7, SG_NONE, 1, 0, 1} #endif