4 #include <linux/genhd.h>
16 #define MAJOR_NR COMPAQ_CISS_MAJOR
19 typedef struct ctlr_info ctlr_info_t;
21 struct access_method {
22 void (*submit_command)(ctlr_info_t *h, CommandList_struct *c);
23 void (*set_intr_mask)(ctlr_info_t *h, unsigned long val);
24 unsigned long (*fifo_full)(ctlr_info_t *h);
25 unsigned long (*intr_pending)(ctlr_info_t *h);
26 unsigned long (*command_completed)(ctlr_info_t *h);
28 typedef struct _drive_info_struct
32 unsigned int nr_blocks;
45 char firm_ver[4]; // Firmware version
50 unsigned long io_mem_addr;
51 unsigned long io_mem_length;
52 CfgTable_struct *cfgtable;
56 int commands_outstanding;
57 int max_outstanding; /* Debug */
60 int usage_count; /* number of opens all all minor devices */
62 // information about each logical volume
63 drive_info_struct drv[CISS_MAX_LUN];
65 struct access_method access;
67 /* queue and queue Info */
68 CommandList_struct *reqQ;
69 CommandList_struct *cmpQ;
71 unsigned int maxQsinceinit;
74 //* pointers to command and error info pool */
75 CommandList_struct *cmd_pool;
76 dma_addr_t cmd_pool_dhandle;
77 ErrorInfo_struct *errinfo_pool;
78 dma_addr_t errinfo_pool_dhandle;
83 // Disk structures we need to pass back
84 struct gendisk gendisk;
85 // indexed by minor numbers
86 struct hd_struct hd[256];
91 #ifdef CONFIG_CISS_SCSI_TAPE
92 void *scsi_ctlr; /* ptr to structure containing scsi related stuff */
96 /* Defining the diffent access_menthods */
98 * Memory mapped FIFO interface (SMART 53xx cards)
100 #define SA5_DOORBELL 0x20
101 #define SA5_REQUEST_PORT_OFFSET 0x40
102 #define SA5_REPLY_INTR_MASK_OFFSET 0x34
103 #define SA5_REPLY_PORT_OFFSET 0x44
104 #define SA5_INTR_STATUS 0x30
106 #define SA5_CTCFG_OFFSET 0xB4
107 #define SA5_CTMEM_OFFSET 0xB8
109 #define SA5_INTR_OFF 0x08
110 #define SA5B_INTR_OFF 0x04
111 #define SA5_INTR_PENDING 0x08
112 #define SA5B_INTR_PENDING 0x04
113 #define FIFO_EMPTY 0xffffffff
115 #define CISS_ERROR_BIT 0x02
117 #define CCISS_INTR_ON 1
118 #define CCISS_INTR_OFF 0
120 Send the command to the hardware
122 static void SA5_submit_command( ctlr_info_t *h, CommandList_struct *c)
125 printk("Sending %x - down to controller\n", c->busaddr );
126 #endif /* CCISS_DEBUG */
127 writel(c->busaddr, h->vaddr + SA5_REQUEST_PORT_OFFSET);
128 h->commands_outstanding++;
129 if ( h->commands_outstanding > h->max_outstanding)
130 h->max_outstanding = h->commands_outstanding;
134 * This card is the opposite of the other cards.
135 * 0 turns interrupts on...
136 * 0x08 turns them off...
138 static void SA5_intr_mask(ctlr_info_t *h, unsigned long val)
141 { /* Turn interrupts on */
142 writel(0, h->vaddr + SA5_REPLY_INTR_MASK_OFFSET);
143 } else /* Turn them off */
145 writel( SA5_INTR_OFF,
146 h->vaddr + SA5_REPLY_INTR_MASK_OFFSET);
150 * This card is the opposite of the other cards.
151 * 0 turns interrupts on...
152 * 0x04 turns them off...
154 static void SA5B_intr_mask(ctlr_info_t *h, unsigned long val)
157 { /* Turn interrupts on */
158 writel(0, h->vaddr + SA5_REPLY_INTR_MASK_OFFSET);
159 } else /* Turn them off */
161 writel( SA5B_INTR_OFF,
162 h->vaddr + SA5_REPLY_INTR_MASK_OFFSET);
166 * Returns true if fifo is full.
169 static unsigned long SA5_fifo_full(ctlr_info_t *h)
171 if( h->commands_outstanding >= h->max_commands)
178 * returns value read from hardware.
179 * returns FIFO_EMPTY if there is nothing to read
181 static unsigned long SA5_completed(ctlr_info_t *h)
183 unsigned long register_value
184 = readl(h->vaddr + SA5_REPLY_PORT_OFFSET);
185 if(register_value != FIFO_EMPTY)
187 h->commands_outstanding--;
189 printk("cciss: Read %lx back from board\n", register_value);
190 #endif /* CCISS_DEBUG */
195 printk("cciss: FIFO Empty read\n");
198 return ( register_value);
202 * Returns true if an interrupt is pending..
204 static unsigned long SA5_intr_pending(ctlr_info_t *h)
206 unsigned long register_value =
207 readl(h->vaddr + SA5_INTR_STATUS);
209 printk("cciss: intr_pending %lx\n", register_value);
210 #endif /* CCISS_DEBUG */
211 if( register_value & SA5_INTR_PENDING)
217 * Returns true if an interrupt is pending..
219 static unsigned long SA5B_intr_pending(ctlr_info_t *h)
221 unsigned long register_value =
222 readl(h->vaddr + SA5_INTR_STATUS);
224 printk("cciss: intr_pending %lx\n", register_value);
225 #endif /* CCISS_DEBUG */
226 if( register_value & SA5B_INTR_PENDING)
232 static struct access_method SA5_access = {
240 static struct access_method SA5B_access = {
251 struct access_method *access;