diff options
Diffstat (limited to 'drivers/block/cciss.h')
-rw-r--r-- | drivers/block/cciss.h | 135 |
1 files changed, 124 insertions, 11 deletions
diff --git a/drivers/block/cciss.h b/drivers/block/cciss.h index c5d411174db0..ae340ffc8f81 100644 --- a/drivers/block/cciss.h +++ b/drivers/block/cciss.h | |||
@@ -25,7 +25,7 @@ struct access_method { | |||
25 | void (*submit_command)(ctlr_info_t *h, CommandList_struct *c); | 25 | void (*submit_command)(ctlr_info_t *h, CommandList_struct *c); |
26 | void (*set_intr_mask)(ctlr_info_t *h, unsigned long val); | 26 | void (*set_intr_mask)(ctlr_info_t *h, unsigned long val); |
27 | unsigned long (*fifo_full)(ctlr_info_t *h); | 27 | unsigned long (*fifo_full)(ctlr_info_t *h); |
28 | unsigned long (*intr_pending)(ctlr_info_t *h); | 28 | bool (*intr_pending)(ctlr_info_t *h); |
29 | unsigned long (*command_completed)(ctlr_info_t *h); | 29 | unsigned long (*command_completed)(ctlr_info_t *h); |
30 | }; | 30 | }; |
31 | typedef struct _drive_info_struct | 31 | typedef struct _drive_info_struct |
@@ -85,8 +85,8 @@ struct ctlr_info | |||
85 | int max_cmd_sgentries; | 85 | int max_cmd_sgentries; |
86 | SGDescriptor_struct **cmd_sg_list; | 86 | SGDescriptor_struct **cmd_sg_list; |
87 | 87 | ||
88 | # define DOORBELL_INT 0 | 88 | # define PERF_MODE_INT 0 |
89 | # define PERF_MODE_INT 1 | 89 | # define DOORBELL_INT 1 |
90 | # define SIMPLE_MODE_INT 2 | 90 | # define SIMPLE_MODE_INT 2 |
91 | # define MEMQ_MODE_INT 3 | 91 | # define MEMQ_MODE_INT 3 |
92 | unsigned int intr[4]; | 92 | unsigned int intr[4]; |
@@ -137,10 +137,27 @@ struct ctlr_info | |||
137 | struct list_head scan_list; | 137 | struct list_head scan_list; |
138 | struct completion scan_wait; | 138 | struct completion scan_wait; |
139 | struct device dev; | 139 | struct device dev; |
140 | /* | ||
141 | * Performant mode tables. | ||
142 | */ | ||
143 | u32 trans_support; | ||
144 | u32 trans_offset; | ||
145 | struct TransTable_struct *transtable; | ||
146 | unsigned long transMethod; | ||
147 | |||
148 | /* | ||
149 | * Performant mode completion buffer | ||
150 | */ | ||
151 | u64 *reply_pool; | ||
152 | dma_addr_t reply_pool_dhandle; | ||
153 | u64 *reply_pool_head; | ||
154 | size_t reply_pool_size; | ||
155 | unsigned char reply_pool_wraparound; | ||
156 | u32 *blockFetchTable; | ||
140 | }; | 157 | }; |
141 | 158 | ||
142 | /* Defining the diffent access_menthods */ | 159 | /* Defining the diffent access_methods |
143 | /* | 160 | * |
144 | * Memory mapped FIFO interface (SMART 53xx cards) | 161 | * Memory mapped FIFO interface (SMART 53xx cards) |
145 | */ | 162 | */ |
146 | #define SA5_DOORBELL 0x20 | 163 | #define SA5_DOORBELL 0x20 |
@@ -159,19 +176,47 @@ struct ctlr_info | |||
159 | #define SA5B_INTR_PENDING 0x04 | 176 | #define SA5B_INTR_PENDING 0x04 |
160 | #define FIFO_EMPTY 0xffffffff | 177 | #define FIFO_EMPTY 0xffffffff |
161 | #define CCISS_FIRMWARE_READY 0xffff0000 /* value in scratchpad register */ | 178 | #define CCISS_FIRMWARE_READY 0xffff0000 /* value in scratchpad register */ |
179 | /* Perf. mode flags */ | ||
180 | #define SA5_PERF_INTR_PENDING 0x04 | ||
181 | #define SA5_PERF_INTR_OFF 0x05 | ||
182 | #define SA5_OUTDB_STATUS_PERF_BIT 0x01 | ||
183 | #define SA5_OUTDB_CLEAR_PERF_BIT 0x01 | ||
184 | #define SA5_OUTDB_CLEAR 0xA0 | ||
185 | #define SA5_OUTDB_CLEAR_PERF_BIT 0x01 | ||
186 | #define SA5_OUTDB_STATUS 0x9C | ||
187 | |||
162 | 188 | ||
163 | #define CISS_ERROR_BIT 0x02 | 189 | #define CISS_ERROR_BIT 0x02 |
164 | 190 | ||
165 | #define CCISS_INTR_ON 1 | 191 | #define CCISS_INTR_ON 1 |
166 | #define CCISS_INTR_OFF 0 | 192 | #define CCISS_INTR_OFF 0 |
193 | |||
194 | |||
195 | /* CCISS_BOARD_READY_WAIT_SECS is how long to wait for a board | ||
196 | * to become ready, in seconds, before giving up on it. | ||
197 | * CCISS_BOARD_READY_POLL_INTERVAL_MSECS * is how long to wait | ||
198 | * between polling the board to see if it is ready, in | ||
199 | * milliseconds. CCISS_BOARD_READY_ITERATIONS is derived | ||
200 | * the above. | ||
201 | */ | ||
202 | #define CCISS_BOARD_READY_WAIT_SECS (120) | ||
203 | #define CCISS_BOARD_READY_POLL_INTERVAL_MSECS (100) | ||
204 | #define CCISS_BOARD_READY_ITERATIONS \ | ||
205 | ((CCISS_BOARD_READY_WAIT_SECS * 1000) / \ | ||
206 | CCISS_BOARD_READY_POLL_INTERVAL_MSECS) | ||
207 | #define CCISS_POST_RESET_PAUSE_MSECS (3000) | ||
208 | #define CCISS_POST_RESET_NOOP_INTERVAL_MSECS (1000) | ||
209 | #define CCISS_POST_RESET_NOOP_RETRIES (12) | ||
210 | |||
167 | /* | 211 | /* |
168 | Send the command to the hardware | 212 | Send the command to the hardware |
169 | */ | 213 | */ |
170 | static void SA5_submit_command( ctlr_info_t *h, CommandList_struct *c) | 214 | static void SA5_submit_command( ctlr_info_t *h, CommandList_struct *c) |
171 | { | 215 | { |
172 | #ifdef CCISS_DEBUG | 216 | #ifdef CCISS_DEBUG |
173 | printk("Sending %x - down to controller\n", c->busaddr ); | 217 | printk(KERN_WARNING "cciss%d: Sending %08x - down to controller\n", |
174 | #endif /* CCISS_DEBUG */ | 218 | h->ctlr, c->busaddr); |
219 | #endif /* CCISS_DEBUG */ | ||
175 | writel(c->busaddr, h->vaddr + SA5_REQUEST_PORT_OFFSET); | 220 | writel(c->busaddr, h->vaddr + SA5_REQUEST_PORT_OFFSET); |
176 | h->commands_outstanding++; | 221 | h->commands_outstanding++; |
177 | if ( h->commands_outstanding > h->max_outstanding) | 222 | if ( h->commands_outstanding > h->max_outstanding) |
@@ -214,6 +259,20 @@ static void SA5B_intr_mask(ctlr_info_t *h, unsigned long val) | |||
214 | h->vaddr + SA5_REPLY_INTR_MASK_OFFSET); | 259 | h->vaddr + SA5_REPLY_INTR_MASK_OFFSET); |
215 | } | 260 | } |
216 | } | 261 | } |
262 | |||
263 | /* Performant mode intr_mask */ | ||
264 | static void SA5_performant_intr_mask(ctlr_info_t *h, unsigned long val) | ||
265 | { | ||
266 | if (val) { /* turn on interrupts */ | ||
267 | h->interrupts_enabled = 1; | ||
268 | writel(0, h->vaddr + SA5_REPLY_INTR_MASK_OFFSET); | ||
269 | } else { | ||
270 | h->interrupts_enabled = 0; | ||
271 | writel(SA5_PERF_INTR_OFF, | ||
272 | h->vaddr + SA5_REPLY_INTR_MASK_OFFSET); | ||
273 | } | ||
274 | } | ||
275 | |||
217 | /* | 276 | /* |
218 | * Returns true if fifo is full. | 277 | * Returns true if fifo is full. |
219 | * | 278 | * |
@@ -250,10 +309,44 @@ static unsigned long SA5_completed(ctlr_info_t *h) | |||
250 | return ( register_value); | 309 | return ( register_value); |
251 | 310 | ||
252 | } | 311 | } |
312 | |||
313 | /* Performant mode command completed */ | ||
314 | static unsigned long SA5_performant_completed(ctlr_info_t *h) | ||
315 | { | ||
316 | unsigned long register_value = FIFO_EMPTY; | ||
317 | |||
318 | /* flush the controller write of the reply queue by reading | ||
319 | * outbound doorbell status register. | ||
320 | */ | ||
321 | register_value = readl(h->vaddr + SA5_OUTDB_STATUS); | ||
322 | /* msi auto clears the interrupt pending bit. */ | ||
323 | if (!(h->msi_vector || h->msix_vector)) { | ||
324 | writel(SA5_OUTDB_CLEAR_PERF_BIT, h->vaddr + SA5_OUTDB_CLEAR); | ||
325 | /* Do a read in order to flush the write to the controller | ||
326 | * (as per spec.) | ||
327 | */ | ||
328 | register_value = readl(h->vaddr + SA5_OUTDB_STATUS); | ||
329 | } | ||
330 | |||
331 | if ((*(h->reply_pool_head) & 1) == (h->reply_pool_wraparound)) { | ||
332 | register_value = *(h->reply_pool_head); | ||
333 | (h->reply_pool_head)++; | ||
334 | h->commands_outstanding--; | ||
335 | } else { | ||
336 | register_value = FIFO_EMPTY; | ||
337 | } | ||
338 | /* Check for wraparound */ | ||
339 | if (h->reply_pool_head == (h->reply_pool + h->max_commands)) { | ||
340 | h->reply_pool_head = h->reply_pool; | ||
341 | h->reply_pool_wraparound ^= 1; | ||
342 | } | ||
343 | |||
344 | return register_value; | ||
345 | } | ||
253 | /* | 346 | /* |
254 | * Returns true if an interrupt is pending.. | 347 | * Returns true if an interrupt is pending.. |
255 | */ | 348 | */ |
256 | static unsigned long SA5_intr_pending(ctlr_info_t *h) | 349 | static bool SA5_intr_pending(ctlr_info_t *h) |
257 | { | 350 | { |
258 | unsigned long register_value = | 351 | unsigned long register_value = |
259 | readl(h->vaddr + SA5_INTR_STATUS); | 352 | readl(h->vaddr + SA5_INTR_STATUS); |
@@ -268,7 +361,7 @@ static unsigned long SA5_intr_pending(ctlr_info_t *h) | |||
268 | /* | 361 | /* |
269 | * Returns true if an interrupt is pending.. | 362 | * Returns true if an interrupt is pending.. |
270 | */ | 363 | */ |
271 | static unsigned long SA5B_intr_pending(ctlr_info_t *h) | 364 | static bool SA5B_intr_pending(ctlr_info_t *h) |
272 | { | 365 | { |
273 | unsigned long register_value = | 366 | unsigned long register_value = |
274 | readl(h->vaddr + SA5_INTR_STATUS); | 367 | readl(h->vaddr + SA5_INTR_STATUS); |
@@ -280,6 +373,20 @@ static unsigned long SA5B_intr_pending(ctlr_info_t *h) | |||
280 | return 0 ; | 373 | return 0 ; |
281 | } | 374 | } |
282 | 375 | ||
376 | static bool SA5_performant_intr_pending(ctlr_info_t *h) | ||
377 | { | ||
378 | unsigned long register_value = readl(h->vaddr + SA5_INTR_STATUS); | ||
379 | |||
380 | if (!register_value) | ||
381 | return false; | ||
382 | |||
383 | if (h->msi_vector || h->msix_vector) | ||
384 | return true; | ||
385 | |||
386 | /* Read outbound doorbell to flush */ | ||
387 | register_value = readl(h->vaddr + SA5_OUTDB_STATUS); | ||
388 | return register_value & SA5_OUTDB_STATUS_PERF_BIT; | ||
389 | } | ||
283 | 390 | ||
284 | static struct access_method SA5_access = { | 391 | static struct access_method SA5_access = { |
285 | SA5_submit_command, | 392 | SA5_submit_command, |
@@ -297,6 +404,14 @@ static struct access_method SA5B_access = { | |||
297 | SA5_completed, | 404 | SA5_completed, |
298 | }; | 405 | }; |
299 | 406 | ||
407 | static struct access_method SA5_performant_access = { | ||
408 | SA5_submit_command, | ||
409 | SA5_performant_intr_mask, | ||
410 | SA5_fifo_full, | ||
411 | SA5_performant_intr_pending, | ||
412 | SA5_performant_completed, | ||
413 | }; | ||
414 | |||
300 | struct board_type { | 415 | struct board_type { |
301 | __u32 board_id; | 416 | __u32 board_id; |
302 | char *product_name; | 417 | char *product_name; |
@@ -304,6 +419,4 @@ struct board_type { | |||
304 | int nr_cmds; /* Max cmds this kind of ctlr can handle. */ | 419 | int nr_cmds; /* Max cmds this kind of ctlr can handle. */ |
305 | }; | 420 | }; |
306 | 421 | ||
307 | #define CCISS_LOCK(i) (&hba[i]->lock) | ||
308 | |||
309 | #endif /* CCISS_H */ | 422 | #endif /* CCISS_H */ |