GUI: Fix Tomato RAF theme for all builds. Compilation typo.
[tomato.git] / release / src-rt-6.x.4708 / linux / linux-2.6.36 / drivers / scsi / 3w-xxxx.c
blobc735d4072c8259ca7b1df234de17ad4f2831784a
3 #include <linux/module.h>
4 #include <linux/reboot.h>
5 #include <linux/smp_lock.h>
6 #include <linux/spinlock.h>
7 #include <linux/interrupt.h>
8 #include <linux/moduleparam.h>
9 #include <linux/errno.h>
10 #include <linux/types.h>
11 #include <linux/delay.h>
12 #include <linux/gfp.h>
13 #include <linux/pci.h>
14 #include <linux/time.h>
15 #include <linux/mutex.h>
16 #include <asm/io.h>
17 #include <asm/irq.h>
18 #include <asm/uaccess.h>
19 #include <scsi/scsi.h>
20 #include <scsi/scsi_host.h>
21 #include <scsi/scsi_tcq.h>
22 #include <scsi/scsi_cmnd.h>
23 #include "3w-xxxx.h"
25 /* Globals */
26 #define TW_DRIVER_VERSION "1.26.02.003"
27 static TW_Device_Extension *tw_device_extension_list[TW_MAX_SLOT];
28 static int tw_device_extension_count = 0;
29 static int twe_major = -1;
31 /* Module parameters */
32 MODULE_AUTHOR("LSI");
33 MODULE_DESCRIPTION("3ware Storage Controller Linux Driver");
34 MODULE_LICENSE("GPL");
35 MODULE_VERSION(TW_DRIVER_VERSION);
37 /* Function prototypes */
38 static int tw_reset_device_extension(TW_Device_Extension *tw_dev);
40 /* Functions */
42 /* This function will check the status register for unexpected bits */
43 static int tw_check_bits(u32 status_reg_value)
45 if ((status_reg_value & TW_STATUS_EXPECTED_BITS) != TW_STATUS_EXPECTED_BITS) {
46 dprintk(KERN_WARNING "3w-xxxx: tw_check_bits(): No expected bits (0x%x).\n", status_reg_value);
47 return 1;
49 if ((status_reg_value & TW_STATUS_UNEXPECTED_BITS) != 0) {
50 dprintk(KERN_WARNING "3w-xxxx: tw_check_bits(): Found unexpected bits (0x%x).\n", status_reg_value);
51 return 1;
54 return 0;
55 } /* End tw_check_bits() */
57 /* This function will print readable messages from status register errors */
58 static int tw_decode_bits(TW_Device_Extension *tw_dev, u32 status_reg_value, int print_host)
60 char host[16];
62 dprintk(KERN_WARNING "3w-xxxx: tw_decode_bits()\n");
64 if (print_host)
65 sprintf(host, " scsi%d:", tw_dev->host->host_no);
66 else
67 host[0] = '\0';
69 if (status_reg_value & TW_STATUS_PCI_PARITY_ERROR) {
70 printk(KERN_WARNING "3w-xxxx:%s PCI Parity Error: clearing.\n", host);
71 outl(TW_CONTROL_CLEAR_PARITY_ERROR, TW_CONTROL_REG_ADDR(tw_dev));
74 if (status_reg_value & TW_STATUS_PCI_ABORT) {
75 printk(KERN_WARNING "3w-xxxx:%s PCI Abort: clearing.\n", host);
76 outl(TW_CONTROL_CLEAR_PCI_ABORT, TW_CONTROL_REG_ADDR(tw_dev));
77 pci_write_config_word(tw_dev->tw_pci_dev, PCI_STATUS, TW_PCI_CLEAR_PCI_ABORT);
80 if (status_reg_value & TW_STATUS_QUEUE_ERROR) {
81 printk(KERN_WARNING "3w-xxxx:%s Controller Queue Error: clearing.\n", host);
82 outl(TW_CONTROL_CLEAR_QUEUE_ERROR, TW_CONTROL_REG_ADDR(tw_dev));
85 if (status_reg_value & TW_STATUS_SBUF_WRITE_ERROR) {
86 printk(KERN_WARNING "3w-xxxx:%s SBUF Write Error: clearing.\n", host);
87 outl(TW_CONTROL_CLEAR_SBUF_WRITE_ERROR, TW_CONTROL_REG_ADDR(tw_dev));
90 if (status_reg_value & TW_STATUS_MICROCONTROLLER_ERROR) {
91 if (tw_dev->reset_print == 0) {
92 printk(KERN_WARNING "3w-xxxx:%s Microcontroller Error: clearing.\n", host);
93 tw_dev->reset_print = 1;
95 return 1;
98 return 0;
99 } /* End tw_decode_bits() */
101 /* This function will poll the status register for a flag */
102 static int tw_poll_status(TW_Device_Extension *tw_dev, u32 flag, int seconds)
104 u32 status_reg_value;
105 unsigned long before;
106 int retval = 1;
108 status_reg_value = inl(TW_STATUS_REG_ADDR(tw_dev));
109 before = jiffies;
111 if (tw_check_bits(status_reg_value))
112 tw_decode_bits(tw_dev, status_reg_value, 0);
114 while ((status_reg_value & flag) != flag) {
115 status_reg_value = inl(TW_STATUS_REG_ADDR(tw_dev));
117 if (tw_check_bits(status_reg_value))
118 tw_decode_bits(tw_dev, status_reg_value, 0);
120 if (time_after(jiffies, before + HZ * seconds))
121 goto out;
123 msleep(50);
125 retval = 0;
126 out:
127 return retval;
128 } /* End tw_poll_status() */
130 /* This function will poll the status register for disappearance of a flag */
131 static int tw_poll_status_gone(TW_Device_Extension *tw_dev, u32 flag, int seconds)
133 u32 status_reg_value;
134 unsigned long before;
135 int retval = 1;
137 status_reg_value = inl(TW_STATUS_REG_ADDR(tw_dev));
138 before = jiffies;
140 if (tw_check_bits(status_reg_value))
141 tw_decode_bits(tw_dev, status_reg_value, 0);
143 while ((status_reg_value & flag) != 0) {
144 status_reg_value = inl(TW_STATUS_REG_ADDR(tw_dev));
146 if (tw_check_bits(status_reg_value))
147 tw_decode_bits(tw_dev, status_reg_value, 0);
149 if (time_after(jiffies, before + HZ * seconds))
150 goto out;
152 msleep(50);
154 retval = 0;
155 out:
156 return retval;
157 } /* End tw_poll_status_gone() */
159 /* This function will attempt to post a command packet to the board */
160 static int tw_post_command_packet(TW_Device_Extension *tw_dev, int request_id)
162 u32 status_reg_value;
163 unsigned long command_que_value;
165 dprintk(KERN_NOTICE "3w-xxxx: tw_post_command_packet()\n");
166 command_que_value = tw_dev->command_packet_physical_address[request_id];
167 status_reg_value = inl(TW_STATUS_REG_ADDR(tw_dev));
169 if (tw_check_bits(status_reg_value)) {
170 dprintk(KERN_WARNING "3w-xxxx: tw_post_command_packet(): Unexpected bits.\n");
171 tw_decode_bits(tw_dev, status_reg_value, 1);
174 if ((status_reg_value & TW_STATUS_COMMAND_QUEUE_FULL) == 0) {
175 /* We successfully posted the command packet */
176 outl(command_que_value, TW_COMMAND_QUEUE_REG_ADDR(tw_dev));
177 tw_dev->state[request_id] = TW_S_POSTED;
178 tw_dev->posted_request_count++;
179 if (tw_dev->posted_request_count > tw_dev->max_posted_request_count) {
180 tw_dev->max_posted_request_count = tw_dev->posted_request_count;
182 } else {
183 /* Couldn't post the command packet, so we do it in the isr */
184 if (tw_dev->state[request_id] != TW_S_PENDING) {
185 tw_dev->state[request_id] = TW_S_PENDING;
186 tw_dev->pending_request_count++;
187 if (tw_dev->pending_request_count > tw_dev->max_pending_request_count) {
188 tw_dev->max_pending_request_count = tw_dev->pending_request_count;
190 tw_dev->pending_queue[tw_dev->pending_tail] = request_id;
191 if (tw_dev->pending_tail == TW_Q_LENGTH-1) {
192 tw_dev->pending_tail = TW_Q_START;
193 } else {
194 tw_dev->pending_tail = tw_dev->pending_tail + 1;
197 TW_UNMASK_COMMAND_INTERRUPT(tw_dev);
198 return 1;
200 return 0;
201 } /* End tw_post_command_packet() */
203 /* This function will return valid sense buffer information for failed cmds */
204 static int tw_decode_sense(TW_Device_Extension *tw_dev, int request_id, int fill_sense)
206 int i;
207 TW_Command *command;
209 dprintk(KERN_WARNING "3w-xxxx: tw_decode_sense()\n");
210 command = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
212 printk(KERN_WARNING "3w-xxxx: scsi%d: Command failed: status = 0x%x, flags = 0x%x, unit #%d.\n", tw_dev->host->host_no, command->status, command->flags, TW_UNIT_OUT(command->unit__hostid));
214 /* Attempt to return intelligent sense information */
215 if (fill_sense) {
216 if ((command->status == 0xc7) || (command->status == 0xcb)) {
217 for (i = 0; i < ARRAY_SIZE(tw_sense_table); i++) {
218 if (command->flags == tw_sense_table[i][0]) {
220 /* Valid bit and 'current errors' */
221 tw_dev->srb[request_id]->sense_buffer[0] = (0x1 << 7 | 0x70);
223 /* Sense key */
224 tw_dev->srb[request_id]->sense_buffer[2] = tw_sense_table[i][1];
226 /* Additional sense length */
227 tw_dev->srb[request_id]->sense_buffer[7] = 0xa; /* 10 bytes */
229 /* Additional sense code */
230 tw_dev->srb[request_id]->sense_buffer[12] = tw_sense_table[i][2];
232 /* Additional sense code qualifier */
233 tw_dev->srb[request_id]->sense_buffer[13] = tw_sense_table[i][3];
235 tw_dev->srb[request_id]->result = (DID_OK << 16) | (CHECK_CONDITION << 1);
236 return TW_ISR_DONT_RESULT; /* Special case for isr to not over-write result */
241 /* If no table match, error so we get a reset */
242 return 1;
245 return 0;
246 } /* End tw_decode_sense() */
248 /* This function will report controller error status */
249 static int tw_check_errors(TW_Device_Extension *tw_dev)
251 u32 status_reg_value;
253 status_reg_value = inl(TW_STATUS_REG_ADDR(tw_dev));
255 if (TW_STATUS_ERRORS(status_reg_value) || tw_check_bits(status_reg_value)) {
256 tw_decode_bits(tw_dev, status_reg_value, 0);
257 return 1;
260 return 0;
261 } /* End tw_check_errors() */
263 /* This function will empty the response que */
264 static void tw_empty_response_que(TW_Device_Extension *tw_dev)
266 u32 status_reg_value, response_que_value;
268 status_reg_value = inl(TW_STATUS_REG_ADDR(tw_dev));
270 while ((status_reg_value & TW_STATUS_RESPONSE_QUEUE_EMPTY) == 0) {
271 response_que_value = inl(TW_RESPONSE_QUEUE_REG_ADDR(tw_dev));
272 status_reg_value = inl(TW_STATUS_REG_ADDR(tw_dev));
274 } /* End tw_empty_response_que() */
276 /* This function will free a request_id */
277 static void tw_state_request_finish(TW_Device_Extension *tw_dev, int request_id)
279 tw_dev->free_queue[tw_dev->free_tail] = request_id;
280 tw_dev->state[request_id] = TW_S_FINISHED;
281 tw_dev->free_tail = (tw_dev->free_tail + 1) % TW_Q_LENGTH;
282 } /* End tw_state_request_finish() */
284 /* This function will assign an available request_id */
285 static void tw_state_request_start(TW_Device_Extension *tw_dev, int *request_id)
287 *request_id = tw_dev->free_queue[tw_dev->free_head];
288 tw_dev->free_head = (tw_dev->free_head + 1) % TW_Q_LENGTH;
289 tw_dev->state[*request_id] = TW_S_STARTED;
290 } /* End tw_state_request_start() */
292 /* Show some statistics about the card */
293 static ssize_t tw_show_stats(struct device *dev, struct device_attribute *attr,
294 char *buf)
296 struct Scsi_Host *host = class_to_shost(dev);
297 TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata;
298 unsigned long flags = 0;
299 ssize_t len;
301 spin_lock_irqsave(tw_dev->host->host_lock, flags);
302 len = snprintf(buf, PAGE_SIZE, "3w-xxxx Driver version: %s\n"
303 "Current commands posted: %4d\n"
304 "Max commands posted: %4d\n"
305 "Current pending commands: %4d\n"
306 "Max pending commands: %4d\n"
307 "Last sgl length: %4d\n"
308 "Max sgl length: %4d\n"
309 "Last sector count: %4d\n"
310 "Max sector count: %4d\n"
311 "SCSI Host Resets: %4d\n"
312 "AEN's: %4d\n",
313 TW_DRIVER_VERSION,
314 tw_dev->posted_request_count,
315 tw_dev->max_posted_request_count,
316 tw_dev->pending_request_count,
317 tw_dev->max_pending_request_count,
318 tw_dev->sgl_entries,
319 tw_dev->max_sgl_entries,
320 tw_dev->sector_count,
321 tw_dev->max_sector_count,
322 tw_dev->num_resets,
323 tw_dev->aen_count);
324 spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
325 return len;
326 } /* End tw_show_stats() */
328 /* This function will set a devices queue depth */
329 static int tw_change_queue_depth(struct scsi_device *sdev, int queue_depth,
330 int reason)
332 if (reason != SCSI_QDEPTH_DEFAULT)
333 return -EOPNOTSUPP;
335 if (queue_depth > TW_Q_LENGTH-2)
336 queue_depth = TW_Q_LENGTH-2;
337 scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG, queue_depth);
338 return queue_depth;
339 } /* End tw_change_queue_depth() */
341 /* Create sysfs 'stats' entry */
342 static struct device_attribute tw_host_stats_attr = {
343 .attr = {
344 .name = "stats",
345 .mode = S_IRUGO,
347 .show = tw_show_stats
350 /* Host attributes initializer */
351 static struct device_attribute *tw_host_attrs[] = {
352 &tw_host_stats_attr,
353 NULL,
356 /* This function will read the aen queue from the isr */
357 static int tw_aen_read_queue(TW_Device_Extension *tw_dev, int request_id)
359 TW_Command *command_packet;
360 TW_Param *param;
361 unsigned long command_que_value;
362 u32 status_reg_value;
363 unsigned long param_value = 0;
365 dprintk(KERN_NOTICE "3w-xxxx: tw_aen_read_queue()\n");
367 status_reg_value = inl(TW_STATUS_REG_ADDR(tw_dev));
368 if (tw_check_bits(status_reg_value)) {
369 dprintk(KERN_WARNING "3w-xxxx: tw_aen_read_queue(): Unexpected bits.\n");
370 tw_decode_bits(tw_dev, status_reg_value, 1);
371 return 1;
373 if (tw_dev->command_packet_virtual_address[request_id] == NULL) {
374 printk(KERN_WARNING "3w-xxxx: tw_aen_read_queue(): Bad command packet virtual address.\n");
375 return 1;
377 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
378 memset(command_packet, 0, sizeof(TW_Sector));
379 command_packet->opcode__sgloffset = TW_OPSGL_IN(2, TW_OP_GET_PARAM);
380 command_packet->size = 4;
381 command_packet->request_id = request_id;
382 command_packet->status = 0;
383 command_packet->flags = 0;
384 command_packet->byte6.parameter_count = 1;
385 command_que_value = tw_dev->command_packet_physical_address[request_id];
386 if (command_que_value == 0) {
387 printk(KERN_WARNING "3w-xxxx: tw_aen_read_queue(): Bad command packet physical address.\n");
388 return 1;
390 /* Now setup the param */
391 if (tw_dev->alignment_virtual_address[request_id] == NULL) {
392 printk(KERN_WARNING "3w-xxxx: tw_aen_read_queue(): Bad alignment virtual address.\n");
393 return 1;
395 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
396 memset(param, 0, sizeof(TW_Sector));
397 param->table_id = 0x401; /* AEN table */
398 param->parameter_id = 2; /* Unit code */
399 param->parameter_size_bytes = 2;
400 param_value = tw_dev->alignment_physical_address[request_id];
401 if (param_value == 0) {
402 printk(KERN_WARNING "3w-xxxx: tw_aen_read_queue(): Bad alignment physical address.\n");
403 return 1;
405 command_packet->byte8.param.sgl[0].address = param_value;
406 command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
408 /* Now post the command packet */
409 if ((status_reg_value & TW_STATUS_COMMAND_QUEUE_FULL) == 0) {
410 dprintk(KERN_WARNING "3w-xxxx: tw_aen_read_queue(): Post succeeded.\n");
411 tw_dev->srb[request_id] = NULL; /* Flag internal command */
412 tw_dev->state[request_id] = TW_S_POSTED;
413 outl(command_que_value, TW_COMMAND_QUEUE_REG_ADDR(tw_dev));
414 } else {
415 printk(KERN_WARNING "3w-xxxx: tw_aen_read_queue(): Post failed, will retry.\n");
416 return 1;
419 return 0;
420 } /* End tw_aen_read_queue() */
422 /* This function will complete an aen request from the isr */
423 static int tw_aen_complete(TW_Device_Extension *tw_dev, int request_id)
425 TW_Param *param;
426 unsigned short aen;
427 int error = 0, table_max = 0;
429 dprintk(KERN_WARNING "3w-xxxx: tw_aen_complete()\n");
430 if (tw_dev->alignment_virtual_address[request_id] == NULL) {
431 printk(KERN_WARNING "3w-xxxx: tw_aen_complete(): Bad alignment virtual address.\n");
432 return 1;
434 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
435 aen = *(unsigned short *)(param->data);
436 dprintk(KERN_NOTICE "3w-xxxx: tw_aen_complete(): Queue'd code 0x%x\n", aen);
438 /* Print some useful info when certain aen codes come out */
439 if (aen == 0x0ff) {
440 printk(KERN_WARNING "3w-xxxx: scsi%d: AEN: INFO: AEN queue overflow.\n", tw_dev->host->host_no);
441 } else {
442 table_max = ARRAY_SIZE(tw_aen_string);
443 if ((aen & 0x0ff) < table_max) {
444 if ((tw_aen_string[aen & 0xff][strlen(tw_aen_string[aen & 0xff])-1]) == '#') {
445 printk(KERN_WARNING "3w-xxxx: scsi%d: AEN: %s%d.\n", tw_dev->host->host_no, tw_aen_string[aen & 0xff], aen >> 8);
446 } else {
447 if (aen != 0x0)
448 printk(KERN_WARNING "3w-xxxx: scsi%d: AEN: %s.\n", tw_dev->host->host_no, tw_aen_string[aen & 0xff]);
450 } else {
451 printk(KERN_WARNING "3w-xxxx: scsi%d: Received AEN %d.\n", tw_dev->host->host_no, aen);
454 if (aen != TW_AEN_QUEUE_EMPTY) {
455 tw_dev->aen_count++;
457 /* Now queue the code */
458 tw_dev->aen_queue[tw_dev->aen_tail] = aen;
459 if (tw_dev->aen_tail == TW_Q_LENGTH - 1) {
460 tw_dev->aen_tail = TW_Q_START;
461 } else {
462 tw_dev->aen_tail = tw_dev->aen_tail + 1;
464 if (tw_dev->aen_head == tw_dev->aen_tail) {
465 if (tw_dev->aen_head == TW_Q_LENGTH - 1) {
466 tw_dev->aen_head = TW_Q_START;
467 } else {
468 tw_dev->aen_head = tw_dev->aen_head + 1;
472 error = tw_aen_read_queue(tw_dev, request_id);
473 if (error) {
474 printk(KERN_WARNING "3w-xxxx: scsi%d: Error completing AEN.\n", tw_dev->host->host_no);
475 tw_dev->state[request_id] = TW_S_COMPLETED;
476 tw_state_request_finish(tw_dev, request_id);
478 } else {
479 tw_dev->state[request_id] = TW_S_COMPLETED;
480 tw_state_request_finish(tw_dev, request_id);
483 return 0;
484 } /* End tw_aen_complete() */
486 /* This function will drain the aen queue after a soft reset */
487 static int tw_aen_drain_queue(TW_Device_Extension *tw_dev)
489 TW_Command *command_packet;
490 TW_Param *param;
491 int request_id = 0;
492 unsigned long command_que_value;
493 unsigned long param_value;
494 TW_Response_Queue response_queue;
495 unsigned short aen;
496 unsigned short aen_code;
497 int finished = 0;
498 int first_reset = 0;
499 int queue = 0;
500 int found = 0, table_max = 0;
502 dprintk(KERN_NOTICE "3w-xxxx: tw_aen_drain_queue()\n");
504 if (tw_poll_status(tw_dev, TW_STATUS_ATTENTION_INTERRUPT | TW_STATUS_MICROCONTROLLER_READY, 30)) {
505 dprintk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): No attention interrupt for card %d.\n", tw_device_extension_count);
506 return 1;
508 TW_CLEAR_ATTENTION_INTERRUPT(tw_dev);
510 /* Empty response queue */
511 tw_empty_response_que(tw_dev);
513 /* Initialize command packet */
514 if (tw_dev->command_packet_virtual_address[request_id] == NULL) {
515 printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Bad command packet virtual address.\n");
516 return 1;
518 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
519 memset(command_packet, 0, sizeof(TW_Sector));
520 command_packet->opcode__sgloffset = TW_OPSGL_IN(2, TW_OP_GET_PARAM);
521 command_packet->size = 4;
522 command_packet->request_id = request_id;
523 command_packet->status = 0;
524 command_packet->flags = 0;
525 command_packet->byte6.parameter_count = 1;
526 command_que_value = tw_dev->command_packet_physical_address[request_id];
527 if (command_que_value == 0) {
528 printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Bad command packet physical address.\n");
529 return 1;
532 /* Now setup the param */
533 if (tw_dev->alignment_virtual_address[request_id] == NULL) {
534 printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Bad alignment virtual address.\n");
535 return 1;
537 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
538 memset(param, 0, sizeof(TW_Sector));
539 param->table_id = 0x401; /* AEN table */
540 param->parameter_id = 2; /* Unit code */
541 param->parameter_size_bytes = 2;
542 param_value = tw_dev->alignment_physical_address[request_id];
543 if (param_value == 0) {
544 printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Bad alignment physical address.\n");
545 return 1;
547 command_packet->byte8.param.sgl[0].address = param_value;
548 command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
550 /* Now drain the controller's aen queue */
551 do {
552 /* Post command packet */
553 outl(command_que_value, TW_COMMAND_QUEUE_REG_ADDR(tw_dev));
555 /* Now poll for completion */
556 if (tw_poll_status_gone(tw_dev, TW_STATUS_RESPONSE_QUEUE_EMPTY, 30) == 0) {
557 response_queue.value = inl(TW_RESPONSE_QUEUE_REG_ADDR(tw_dev));
558 request_id = TW_RESID_OUT(response_queue.response_id);
560 if (request_id != 0) {
561 /* Unexpected request id */
562 printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Unexpected request id.\n");
563 return 1;
566 if (command_packet->status != 0) {
567 if (command_packet->flags != TW_AEN_TABLE_UNDEFINED) {
568 /* Bad response */
569 tw_decode_sense(tw_dev, request_id, 0);
570 return 1;
571 } else {
572 /* We know this is a 3w-1x00, and doesn't support aen's */
573 return 0;
577 /* Now check the aen */
578 aen = *(unsigned short *)(param->data);
579 aen_code = (aen & 0x0ff);
580 queue = 0;
581 switch (aen_code) {
582 case TW_AEN_QUEUE_EMPTY:
583 dprintk(KERN_WARNING "3w-xxxx: AEN: %s.\n", tw_aen_string[aen & 0xff]);
584 if (first_reset != 1) {
585 return 1;
586 } else {
587 finished = 1;
589 break;
590 case TW_AEN_SOFT_RESET:
591 if (first_reset == 0) {
592 first_reset = 1;
593 } else {
594 printk(KERN_WARNING "3w-xxxx: AEN: %s.\n", tw_aen_string[aen & 0xff]);
595 tw_dev->aen_count++;
596 queue = 1;
598 break;
599 default:
600 if (aen == 0x0ff) {
601 printk(KERN_WARNING "3w-xxxx: AEN: INFO: AEN queue overflow.\n");
602 } else {
603 table_max = ARRAY_SIZE(tw_aen_string);
604 if ((aen & 0x0ff) < table_max) {
605 if ((tw_aen_string[aen & 0xff][strlen(tw_aen_string[aen & 0xff])-1]) == '#') {
606 printk(KERN_WARNING "3w-xxxx: AEN: %s%d.\n", tw_aen_string[aen & 0xff], aen >> 8);
607 } else {
608 printk(KERN_WARNING "3w-xxxx: AEN: %s.\n", tw_aen_string[aen & 0xff]);
610 } else
611 printk(KERN_WARNING "3w-xxxx: Received AEN %d.\n", aen);
613 tw_dev->aen_count++;
614 queue = 1;
617 /* Now put the aen on the aen_queue */
618 if (queue == 1) {
619 tw_dev->aen_queue[tw_dev->aen_tail] = aen;
620 if (tw_dev->aen_tail == TW_Q_LENGTH - 1) {
621 tw_dev->aen_tail = TW_Q_START;
622 } else {
623 tw_dev->aen_tail = tw_dev->aen_tail + 1;
625 if (tw_dev->aen_head == tw_dev->aen_tail) {
626 if (tw_dev->aen_head == TW_Q_LENGTH - 1) {
627 tw_dev->aen_head = TW_Q_START;
628 } else {
629 tw_dev->aen_head = tw_dev->aen_head + 1;
633 found = 1;
635 if (found == 0) {
636 printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Response never received.\n");
637 return 1;
639 } while (finished == 0);
641 return 0;
642 } /* End tw_aen_drain_queue() */
644 /* This function will allocate memory */
645 static int tw_allocate_memory(TW_Device_Extension *tw_dev, int size, int which)
647 int i;
648 dma_addr_t dma_handle;
649 unsigned long *cpu_addr = NULL;
651 dprintk(KERN_NOTICE "3w-xxxx: tw_allocate_memory()\n");
653 cpu_addr = pci_alloc_consistent(tw_dev->tw_pci_dev, size*TW_Q_LENGTH, &dma_handle);
654 if (cpu_addr == NULL) {
655 printk(KERN_WARNING "3w-xxxx: pci_alloc_consistent() failed.\n");
656 return 1;
659 if ((unsigned long)cpu_addr % (tw_dev->tw_pci_dev->device == TW_DEVICE_ID ? TW_ALIGNMENT_6000 : TW_ALIGNMENT_7000)) {
660 printk(KERN_WARNING "3w-xxxx: Couldn't allocate correctly aligned memory.\n");
661 pci_free_consistent(tw_dev->tw_pci_dev, size*TW_Q_LENGTH, cpu_addr, dma_handle);
662 return 1;
665 memset(cpu_addr, 0, size*TW_Q_LENGTH);
667 for (i=0;i<TW_Q_LENGTH;i++) {
668 switch(which) {
669 case 0:
670 tw_dev->command_packet_physical_address[i] = dma_handle+(i*size);
671 tw_dev->command_packet_virtual_address[i] = (unsigned long *)((unsigned char *)cpu_addr + (i*size));
672 break;
673 case 1:
674 tw_dev->alignment_physical_address[i] = dma_handle+(i*size);
675 tw_dev->alignment_virtual_address[i] = (unsigned long *)((unsigned char *)cpu_addr + (i*size));
676 break;
677 default:
678 printk(KERN_WARNING "3w-xxxx: tw_allocate_memory(): case slip in tw_allocate_memory()\n");
679 return 1;
683 return 0;
684 } /* End tw_allocate_memory() */
686 /* This function handles ioctl for the character device */
687 static long tw_chrdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
689 int request_id;
690 dma_addr_t dma_handle;
691 unsigned short tw_aen_code;
692 unsigned long flags;
693 unsigned int data_buffer_length = 0;
694 unsigned long data_buffer_length_adjusted = 0;
695 struct inode *inode = file->f_dentry->d_inode;
696 unsigned long *cpu_addr;
697 long timeout;
698 TW_New_Ioctl *tw_ioctl;
699 TW_Passthru *passthru;
700 TW_Device_Extension *tw_dev = tw_device_extension_list[iminor(inode)];
701 int retval = -EFAULT;
702 void __user *argp = (void __user *)arg;
704 dprintk(KERN_WARNING "3w-xxxx: tw_chrdev_ioctl()\n");
706 lock_kernel();
707 /* Only let one of these through at a time */
708 if (mutex_lock_interruptible(&tw_dev->ioctl_lock)) {
709 unlock_kernel();
710 return -EINTR;
713 /* First copy down the buffer length */
714 if (copy_from_user(&data_buffer_length, argp, sizeof(unsigned int)))
715 goto out;
717 /* Check size */
718 if (data_buffer_length > TW_MAX_IOCTL_SECTORS * 512) {
719 retval = -EINVAL;
720 goto out;
723 /* Hardware can only do multiple of 512 byte transfers */
724 data_buffer_length_adjusted = (data_buffer_length + 511) & ~511;
726 /* Now allocate ioctl buf memory */
727 cpu_addr = dma_alloc_coherent(&tw_dev->tw_pci_dev->dev, data_buffer_length_adjusted+sizeof(TW_New_Ioctl) - 1, &dma_handle, GFP_KERNEL);
728 if (cpu_addr == NULL) {
729 retval = -ENOMEM;
730 goto out;
733 tw_ioctl = (TW_New_Ioctl *)cpu_addr;
735 /* Now copy down the entire ioctl */
736 if (copy_from_user(tw_ioctl, argp, data_buffer_length + sizeof(TW_New_Ioctl) - 1))
737 goto out2;
739 passthru = (TW_Passthru *)&tw_ioctl->firmware_command;
741 /* See which ioctl we are doing */
742 switch (cmd) {
743 case TW_OP_NOP:
744 dprintk(KERN_WARNING "3w-xxxx: tw_chrdev_ioctl(): caught TW_OP_NOP.\n");
745 break;
746 case TW_OP_AEN_LISTEN:
747 dprintk(KERN_WARNING "3w-xxxx: tw_chrdev_ioctl(): caught TW_AEN_LISTEN.\n");
748 memset(tw_ioctl->data_buffer, 0, data_buffer_length);
750 spin_lock_irqsave(tw_dev->host->host_lock, flags);
751 if (tw_dev->aen_head == tw_dev->aen_tail) {
752 tw_aen_code = TW_AEN_QUEUE_EMPTY;
753 } else {
754 tw_aen_code = tw_dev->aen_queue[tw_dev->aen_head];
755 if (tw_dev->aen_head == TW_Q_LENGTH - 1) {
756 tw_dev->aen_head = TW_Q_START;
757 } else {
758 tw_dev->aen_head = tw_dev->aen_head + 1;
761 spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
762 memcpy(tw_ioctl->data_buffer, &tw_aen_code, sizeof(tw_aen_code));
763 break;
764 case TW_CMD_PACKET_WITH_DATA:
765 dprintk(KERN_WARNING "3w-xxxx: tw_chrdev_ioctl(): caught TW_CMD_PACKET_WITH_DATA.\n");
766 spin_lock_irqsave(tw_dev->host->host_lock, flags);
768 tw_state_request_start(tw_dev, &request_id);
770 /* Flag internal command */
771 tw_dev->srb[request_id] = NULL;
773 /* Flag chrdev ioctl */
774 tw_dev->chrdev_request_id = request_id;
776 tw_ioctl->firmware_command.request_id = request_id;
778 /* Load the sg list */
779 switch (TW_SGL_OUT(tw_ioctl->firmware_command.opcode__sgloffset)) {
780 case 2:
781 tw_ioctl->firmware_command.byte8.param.sgl[0].address = dma_handle + sizeof(TW_New_Ioctl) - 1;
782 tw_ioctl->firmware_command.byte8.param.sgl[0].length = data_buffer_length_adjusted;
783 break;
784 case 3:
785 tw_ioctl->firmware_command.byte8.io.sgl[0].address = dma_handle + sizeof(TW_New_Ioctl) - 1;
786 tw_ioctl->firmware_command.byte8.io.sgl[0].length = data_buffer_length_adjusted;
787 break;
788 case 5:
789 passthru->sg_list[0].address = dma_handle + sizeof(TW_New_Ioctl) - 1;
790 passthru->sg_list[0].length = data_buffer_length_adjusted;
791 break;
794 memcpy(tw_dev->command_packet_virtual_address[request_id], &(tw_ioctl->firmware_command), sizeof(TW_Command));
796 /* Now post the command packet to the controller */
797 tw_post_command_packet(tw_dev, request_id);
798 spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
800 timeout = TW_IOCTL_CHRDEV_TIMEOUT*HZ;
802 /* Now wait for the command to complete */
803 timeout = wait_event_timeout(tw_dev->ioctl_wqueue, tw_dev->chrdev_request_id == TW_IOCTL_CHRDEV_FREE, timeout);
805 /* We timed out, and didn't get an interrupt */
806 if (tw_dev->chrdev_request_id != TW_IOCTL_CHRDEV_FREE) {
807 /* Now we need to reset the board */
808 printk(KERN_WARNING "3w-xxxx: scsi%d: Character ioctl (0x%x) timed out, resetting card.\n", tw_dev->host->host_no, cmd);
809 retval = -EIO;
810 if (tw_reset_device_extension(tw_dev)) {
811 printk(KERN_WARNING "3w-xxxx: tw_chrdev_ioctl(): Reset failed for card %d.\n", tw_dev->host->host_no);
813 goto out2;
816 /* Now copy in the command packet response */
817 memcpy(&(tw_ioctl->firmware_command), tw_dev->command_packet_virtual_address[request_id], sizeof(TW_Command));
819 /* Now complete the io */
820 spin_lock_irqsave(tw_dev->host->host_lock, flags);
821 tw_dev->posted_request_count--;
822 tw_dev->state[request_id] = TW_S_COMPLETED;
823 tw_state_request_finish(tw_dev, request_id);
824 spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
825 break;
826 default:
827 retval = -ENOTTY;
828 goto out2;
831 /* Now copy the response to userspace */
832 if (copy_to_user(argp, tw_ioctl, sizeof(TW_New_Ioctl) + data_buffer_length - 1))
833 goto out2;
834 retval = 0;
835 out2:
836 /* Now free ioctl buf memory */
837 dma_free_coherent(&tw_dev->tw_pci_dev->dev, data_buffer_length_adjusted+sizeof(TW_New_Ioctl) - 1, cpu_addr, dma_handle);
838 out:
839 mutex_unlock(&tw_dev->ioctl_lock);
840 unlock_kernel();
841 return retval;
842 } /* End tw_chrdev_ioctl() */
844 /* This function handles open for the character device */
845 /* NOTE that this function races with remove. */
846 static int tw_chrdev_open(struct inode *inode, struct file *file)
848 unsigned int minor_number;
850 cycle_kernel_lock();
851 dprintk(KERN_WARNING "3w-xxxx: tw_ioctl_open()\n");
853 minor_number = iminor(inode);
854 if (minor_number >= tw_device_extension_count)
855 return -ENODEV;
857 return 0;
858 } /* End tw_chrdev_open() */
860 /* File operations struct for character device */
861 static const struct file_operations tw_fops = {
862 .owner = THIS_MODULE,
863 .unlocked_ioctl = tw_chrdev_ioctl,
864 .open = tw_chrdev_open,
865 .release = NULL
868 /* This function will free up device extension resources */
869 static void tw_free_device_extension(TW_Device_Extension *tw_dev)
871 dprintk(KERN_NOTICE "3w-xxxx: tw_free_device_extension()\n");
873 /* Free command packet and generic buffer memory */
874 if (tw_dev->command_packet_virtual_address[0])
875 pci_free_consistent(tw_dev->tw_pci_dev, sizeof(TW_Command)*TW_Q_LENGTH, tw_dev->command_packet_virtual_address[0], tw_dev->command_packet_physical_address[0]);
877 if (tw_dev->alignment_virtual_address[0])
878 pci_free_consistent(tw_dev->tw_pci_dev, sizeof(TW_Sector)*TW_Q_LENGTH, tw_dev->alignment_virtual_address[0], tw_dev->alignment_physical_address[0]);
879 } /* End tw_free_device_extension() */
881 /* This function will send an initconnection command to controller */
882 static int tw_initconnection(TW_Device_Extension *tw_dev, int message_credits)
884 unsigned long command_que_value;
885 TW_Command *command_packet;
886 TW_Response_Queue response_queue;
887 int request_id = 0;
889 dprintk(KERN_NOTICE "3w-xxxx: tw_initconnection()\n");
891 /* Initialize InitConnection command packet */
892 if (tw_dev->command_packet_virtual_address[request_id] == NULL) {
893 printk(KERN_WARNING "3w-xxxx: tw_initconnection(): Bad command packet virtual address.\n");
894 return 1;
897 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
898 memset(command_packet, 0, sizeof(TW_Sector));
899 command_packet->opcode__sgloffset = TW_OPSGL_IN(0, TW_OP_INIT_CONNECTION);
900 command_packet->size = TW_INIT_COMMAND_PACKET_SIZE;
901 command_packet->request_id = request_id;
902 command_packet->status = 0x0;
903 command_packet->flags = 0x0;
904 command_packet->byte6.message_credits = message_credits;
905 command_packet->byte8.init_connection.response_queue_pointer = 0x0;
906 command_que_value = tw_dev->command_packet_physical_address[request_id];
908 if (command_que_value == 0) {
909 printk(KERN_WARNING "3w-xxxx: tw_initconnection(): Bad command packet physical address.\n");
910 return 1;
913 /* Send command packet to the board */
914 outl(command_que_value, TW_COMMAND_QUEUE_REG_ADDR(tw_dev));
916 /* Poll for completion */
917 if (tw_poll_status_gone(tw_dev, TW_STATUS_RESPONSE_QUEUE_EMPTY, 30) == 0) {
918 response_queue.value = inl(TW_RESPONSE_QUEUE_REG_ADDR(tw_dev));
919 request_id = TW_RESID_OUT(response_queue.response_id);
921 if (request_id != 0) {
922 /* unexpected request id */
923 printk(KERN_WARNING "3w-xxxx: tw_initconnection(): Unexpected request id.\n");
924 return 1;
926 if (command_packet->status != 0) {
927 /* bad response */
928 tw_decode_sense(tw_dev, request_id, 0);
929 return 1;
932 return 0;
933 } /* End tw_initconnection() */
935 /* Set a value in the features table */
936 static int tw_setfeature(TW_Device_Extension *tw_dev, int parm, int param_size,
937 unsigned char *val)
939 TW_Param *param;
940 TW_Command *command_packet;
941 TW_Response_Queue response_queue;
942 int request_id = 0;
943 unsigned long command_que_value;
944 unsigned long param_value;
946 /* Initialize SetParam command packet */
947 if (tw_dev->command_packet_virtual_address[request_id] == NULL) {
948 printk(KERN_WARNING "3w-xxxx: tw_setfeature(): Bad command packet virtual address.\n");
949 return 1;
951 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
952 memset(command_packet, 0, sizeof(TW_Sector));
953 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
955 command_packet->opcode__sgloffset = TW_OPSGL_IN(2, TW_OP_SET_PARAM);
956 param->table_id = 0x404; /* Features table */
957 param->parameter_id = parm;
958 param->parameter_size_bytes = param_size;
959 memcpy(param->data, val, param_size);
961 param_value = tw_dev->alignment_physical_address[request_id];
962 if (param_value == 0) {
963 printk(KERN_WARNING "3w-xxxx: tw_setfeature(): Bad alignment physical address.\n");
964 tw_dev->state[request_id] = TW_S_COMPLETED;
965 tw_state_request_finish(tw_dev, request_id);
966 tw_dev->srb[request_id]->result = (DID_OK << 16);
967 tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
969 command_packet->byte8.param.sgl[0].address = param_value;
970 command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
972 command_packet->size = 4;
973 command_packet->request_id = request_id;
974 command_packet->byte6.parameter_count = 1;
976 command_que_value = tw_dev->command_packet_physical_address[request_id];
977 if (command_que_value == 0) {
978 printk(KERN_WARNING "3w-xxxx: tw_setfeature(): Bad command packet physical address.\n");
979 return 1;
982 /* Send command packet to the board */
983 outl(command_que_value, TW_COMMAND_QUEUE_REG_ADDR(tw_dev));
985 /* Poll for completion */
986 if (tw_poll_status_gone(tw_dev, TW_STATUS_RESPONSE_QUEUE_EMPTY, 30) == 0) {
987 response_queue.value = inl(TW_RESPONSE_QUEUE_REG_ADDR(tw_dev));
988 request_id = TW_RESID_OUT(response_queue.response_id);
990 if (request_id != 0) {
991 /* unexpected request id */
992 printk(KERN_WARNING "3w-xxxx: tw_setfeature(): Unexpected request id.\n");
993 return 1;
995 if (command_packet->status != 0) {
996 /* bad response */
997 tw_decode_sense(tw_dev, request_id, 0);
998 return 1;
1002 return 0;
1003 } /* End tw_setfeature() */
1005 /* This function will reset a controller */
1006 static int tw_reset_sequence(TW_Device_Extension *tw_dev)
1008 int error = 0;
1009 int tries = 0;
1010 unsigned char c = 1;
1012 /* Reset the board */
1013 while (tries < TW_MAX_RESET_TRIES) {
1014 TW_SOFT_RESET(tw_dev);
1016 error = tw_aen_drain_queue(tw_dev);
1017 if (error) {
1018 printk(KERN_WARNING "3w-xxxx: scsi%d: AEN drain failed, retrying.\n", tw_dev->host->host_no);
1019 tries++;
1020 continue;
1023 /* Check for controller errors */
1024 if (tw_check_errors(tw_dev)) {
1025 printk(KERN_WARNING "3w-xxxx: scsi%d: Controller errors found, retrying.\n", tw_dev->host->host_no);
1026 tries++;
1027 continue;
1030 /* Now the controller is in a good state */
1031 break;
1034 if (tries >= TW_MAX_RESET_TRIES) {
1035 printk(KERN_WARNING "3w-xxxx: scsi%d: Controller errors, card not responding, check all cabling.\n", tw_dev->host->host_no);
1036 return 1;
1039 error = tw_initconnection(tw_dev, TW_INIT_MESSAGE_CREDITS);
1040 if (error) {
1041 printk(KERN_WARNING "3w-xxxx: scsi%d: Connection initialization failed.\n", tw_dev->host->host_no);
1042 return 1;
1045 error = tw_setfeature(tw_dev, 2, 1, &c);
1046 if (error) {
1047 printk(KERN_WARNING "3w-xxxx: Unable to set features for card, probable old firmware or card.\n");
1050 return 0;
1051 } /* End tw_reset_sequence() */
1053 /* This function will initialize the fields of a device extension */
1054 static int tw_initialize_device_extension(TW_Device_Extension *tw_dev)
1056 int i, error=0;
1058 dprintk(KERN_NOTICE "3w-xxxx: tw_initialize_device_extension()\n");
1060 /* Initialize command packet buffers */
1061 error = tw_allocate_memory(tw_dev, sizeof(TW_Command), 0);
1062 if (error) {
1063 printk(KERN_WARNING "3w-xxxx: Command packet memory allocation failed.\n");
1064 return 1;
1067 /* Initialize generic buffer */
1068 error = tw_allocate_memory(tw_dev, sizeof(TW_Sector), 1);
1069 if (error) {
1070 printk(KERN_WARNING "3w-xxxx: Generic memory allocation failed.\n");
1071 return 1;
1074 for (i=0;i<TW_Q_LENGTH;i++) {
1075 tw_dev->free_queue[i] = i;
1076 tw_dev->state[i] = TW_S_INITIAL;
1079 tw_dev->pending_head = TW_Q_START;
1080 tw_dev->pending_tail = TW_Q_START;
1081 tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE;
1083 mutex_init(&tw_dev->ioctl_lock);
1084 init_waitqueue_head(&tw_dev->ioctl_wqueue);
1086 return 0;
1087 } /* End tw_initialize_device_extension() */
1089 static int tw_map_scsi_sg_data(struct pci_dev *pdev, struct scsi_cmnd *cmd)
1091 int use_sg;
1093 dprintk(KERN_WARNING "3w-xxxx: tw_map_scsi_sg_data()\n");
1095 use_sg = scsi_dma_map(cmd);
1096 if (use_sg < 0) {
1097 printk(KERN_WARNING "3w-xxxx: tw_map_scsi_sg_data(): pci_map_sg() failed.\n");
1098 return 0;
1101 cmd->SCp.phase = TW_PHASE_SGLIST;
1102 cmd->SCp.have_data_in = use_sg;
1104 return use_sg;
1105 } /* End tw_map_scsi_sg_data() */
1107 static void tw_unmap_scsi_data(struct pci_dev *pdev, struct scsi_cmnd *cmd)
1109 dprintk(KERN_WARNING "3w-xxxx: tw_unmap_scsi_data()\n");
1111 if (cmd->SCp.phase == TW_PHASE_SGLIST)
1112 scsi_dma_unmap(cmd);
1113 } /* End tw_unmap_scsi_data() */
1115 /* This function will reset a device extension */
1116 static int tw_reset_device_extension(TW_Device_Extension *tw_dev)
1118 int i = 0;
1119 struct scsi_cmnd *srb;
1120 unsigned long flags = 0;
1122 dprintk(KERN_NOTICE "3w-xxxx: tw_reset_device_extension()\n");
1124 set_bit(TW_IN_RESET, &tw_dev->flags);
1125 TW_DISABLE_INTERRUPTS(tw_dev);
1126 TW_MASK_COMMAND_INTERRUPT(tw_dev);
1127 spin_lock_irqsave(tw_dev->host->host_lock, flags);
1129 /* Abort all requests that are in progress */
1130 for (i=0;i<TW_Q_LENGTH;i++) {
1131 if ((tw_dev->state[i] != TW_S_FINISHED) &&
1132 (tw_dev->state[i] != TW_S_INITIAL) &&
1133 (tw_dev->state[i] != TW_S_COMPLETED)) {
1134 srb = tw_dev->srb[i];
1135 if (srb != NULL) {
1136 srb->result = (DID_RESET << 16);
1137 tw_dev->srb[i]->scsi_done(tw_dev->srb[i]);
1138 tw_unmap_scsi_data(tw_dev->tw_pci_dev, tw_dev->srb[i]);
1143 /* Reset queues and counts */
1144 for (i=0;i<TW_Q_LENGTH;i++) {
1145 tw_dev->free_queue[i] = i;
1146 tw_dev->state[i] = TW_S_INITIAL;
1148 tw_dev->free_head = TW_Q_START;
1149 tw_dev->free_tail = TW_Q_START;
1150 tw_dev->posted_request_count = 0;
1151 tw_dev->pending_request_count = 0;
1152 tw_dev->pending_head = TW_Q_START;
1153 tw_dev->pending_tail = TW_Q_START;
1154 tw_dev->reset_print = 0;
1156 spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
1158 if (tw_reset_sequence(tw_dev)) {
1159 printk(KERN_WARNING "3w-xxxx: scsi%d: Reset sequence failed.\n", tw_dev->host->host_no);
1160 return 1;
1163 TW_ENABLE_AND_CLEAR_INTERRUPTS(tw_dev);
1164 clear_bit(TW_IN_RESET, &tw_dev->flags);
1165 tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE;
1167 return 0;
1168 } /* End tw_reset_device_extension() */
1170 /* This funciton returns unit geometry in cylinders/heads/sectors */
1171 static int tw_scsi_biosparam(struct scsi_device *sdev, struct block_device *bdev,
1172 sector_t capacity, int geom[])
1174 int heads, sectors, cylinders;
1175 TW_Device_Extension *tw_dev;
1177 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_biosparam()\n");
1178 tw_dev = (TW_Device_Extension *)sdev->host->hostdata;
1180 heads = 64;
1181 sectors = 32;
1182 cylinders = sector_div(capacity, heads * sectors);
1184 if (capacity >= 0x200000) {
1185 heads = 255;
1186 sectors = 63;
1187 cylinders = sector_div(capacity, heads * sectors);
1190 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_biosparam(): heads = %d, sectors = %d, cylinders = %d\n", heads, sectors, cylinders);
1191 geom[0] = heads;
1192 geom[1] = sectors;
1193 geom[2] = cylinders;
1195 return 0;
1196 } /* End tw_scsi_biosparam() */
1198 /* This is the new scsi eh reset function */
1199 static int tw_scsi_eh_reset(struct scsi_cmnd *SCpnt)
1201 TW_Device_Extension *tw_dev=NULL;
1202 int retval = FAILED;
1204 tw_dev = (TW_Device_Extension *)SCpnt->device->host->hostdata;
1206 tw_dev->num_resets++;
1208 sdev_printk(KERN_WARNING, SCpnt->device,
1209 "WARNING: Command (0x%x) timed out, resetting card.\n",
1210 SCpnt->cmnd[0]);
1212 /* Make sure we are not issuing an ioctl or resetting from ioctl */
1213 mutex_lock(&tw_dev->ioctl_lock);
1215 /* Now reset the card and some of the device extension data */
1216 if (tw_reset_device_extension(tw_dev)) {
1217 printk(KERN_WARNING "3w-xxxx: scsi%d: Reset failed.\n", tw_dev->host->host_no);
1218 goto out;
1221 retval = SUCCESS;
1222 out:
1223 mutex_unlock(&tw_dev->ioctl_lock);
1224 return retval;
1225 } /* End tw_scsi_eh_reset() */
1227 /* This function handles scsi inquiry commands */
1228 static int tw_scsiop_inquiry(TW_Device_Extension *tw_dev, int request_id)
1230 TW_Param *param;
1231 TW_Command *command_packet;
1232 unsigned long command_que_value;
1233 unsigned long param_value;
1235 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_inquiry()\n");
1237 /* Initialize command packet */
1238 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
1239 if (command_packet == NULL) {
1240 printk(KERN_WARNING "3w-xxxx: tw_scsiop_inquiry(): Bad command packet virtual address.\n");
1241 return 1;
1243 memset(command_packet, 0, sizeof(TW_Sector));
1244 command_packet->opcode__sgloffset = TW_OPSGL_IN(2, TW_OP_GET_PARAM);
1245 command_packet->size = 4;
1246 command_packet->request_id = request_id;
1247 command_packet->status = 0;
1248 command_packet->flags = 0;
1249 command_packet->byte6.parameter_count = 1;
1251 /* Now setup the param */
1252 if (tw_dev->alignment_virtual_address[request_id] == NULL) {
1253 printk(KERN_WARNING "3w-xxxx: tw_scsiop_inquiry(): Bad alignment virtual address.\n");
1254 return 1;
1256 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
1257 memset(param, 0, sizeof(TW_Sector));
1258 param->table_id = 3; /* unit summary table */
1259 param->parameter_id = 3; /* unitsstatus parameter */
1260 param->parameter_size_bytes = TW_MAX_UNITS;
1261 param_value = tw_dev->alignment_physical_address[request_id];
1262 if (param_value == 0) {
1263 printk(KERN_WARNING "3w-xxxx: tw_scsiop_inquiry(): Bad alignment physical address.\n");
1264 return 1;
1267 command_packet->byte8.param.sgl[0].address = param_value;
1268 command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
1269 command_que_value = tw_dev->command_packet_physical_address[request_id];
1270 if (command_que_value == 0) {
1271 printk(KERN_WARNING "3w-xxxx: tw_scsiop_inquiry(): Bad command packet physical address.\n");
1272 return 1;
1275 /* Now try to post the command packet */
1276 tw_post_command_packet(tw_dev, request_id);
1278 return 0;
1279 } /* End tw_scsiop_inquiry() */
1281 static void tw_transfer_internal(TW_Device_Extension *tw_dev, int request_id,
1282 void *data, unsigned int len)
1284 scsi_sg_copy_from_buffer(tw_dev->srb[request_id], data, len);
1287 /* This function is called by the isr to complete an inquiry command */
1288 static int tw_scsiop_inquiry_complete(TW_Device_Extension *tw_dev, int request_id)
1290 unsigned char *is_unit_present;
1291 unsigned char request_buffer[36];
1292 TW_Param *param;
1294 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_inquiry_complete()\n");
1296 memset(request_buffer, 0, sizeof(request_buffer));
1297 request_buffer[0] = TYPE_DISK; /* Peripheral device type */
1298 request_buffer[1] = 0; /* Device type modifier */
1299 request_buffer[2] = 0; /* No ansi/iso compliance */
1300 request_buffer[4] = 31; /* Additional length */
1301 memcpy(&request_buffer[8], "3ware ", 8); /* Vendor ID */
1302 sprintf(&request_buffer[16], "Logical Disk %-2d ", tw_dev->srb[request_id]->device->id);
1303 memcpy(&request_buffer[32], TW_DRIVER_VERSION, 3);
1304 tw_transfer_internal(tw_dev, request_id, request_buffer,
1305 sizeof(request_buffer));
1307 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
1308 if (param == NULL) {
1309 printk(KERN_WARNING "3w-xxxx: tw_scsiop_inquiry_complete(): Bad alignment virtual address.\n");
1310 return 1;
1312 is_unit_present = &(param->data[0]);
1314 if (is_unit_present[tw_dev->srb[request_id]->device->id] & TW_UNIT_ONLINE) {
1315 tw_dev->is_unit_present[tw_dev->srb[request_id]->device->id] = 1;
1316 } else {
1317 tw_dev->is_unit_present[tw_dev->srb[request_id]->device->id] = 0;
1318 tw_dev->srb[request_id]->result = (DID_BAD_TARGET << 16);
1319 return TW_ISR_DONT_RESULT;
1322 return 0;
1323 } /* End tw_scsiop_inquiry_complete() */
1325 /* This function handles scsi mode_sense commands */
1326 static int tw_scsiop_mode_sense(TW_Device_Extension *tw_dev, int request_id)
1328 TW_Param *param;
1329 TW_Command *command_packet;
1330 unsigned long command_que_value;
1331 unsigned long param_value;
1333 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_mode_sense()\n");
1335 /* Only page control = 0, page code = 0x8 (cache page) supported */
1336 if (tw_dev->srb[request_id]->cmnd[2] != 0x8) {
1337 tw_dev->state[request_id] = TW_S_COMPLETED;
1338 tw_state_request_finish(tw_dev, request_id);
1339 tw_dev->srb[request_id]->result = (DID_OK << 16);
1340 tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
1341 return 0;
1344 /* Now read firmware cache setting for this unit */
1345 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
1346 if (command_packet == NULL) {
1347 printk(KERN_WARNING "3w-xxxx: tw_scsiop_mode_sense(): Bad command packet virtual address.\n");
1348 return 1;
1351 /* Setup the command packet */
1352 memset(command_packet, 0, sizeof(TW_Sector));
1353 command_packet->opcode__sgloffset = TW_OPSGL_IN(2, TW_OP_GET_PARAM);
1354 command_packet->size = 4;
1355 command_packet->request_id = request_id;
1356 command_packet->status = 0;
1357 command_packet->flags = 0;
1358 command_packet->byte6.parameter_count = 1;
1360 /* Setup the param */
1361 if (tw_dev->alignment_virtual_address[request_id] == NULL) {
1362 printk(KERN_WARNING "3w-xxxx: tw_scsiop_mode_sense(): Bad alignment virtual address.\n");
1363 return 1;
1366 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
1367 memset(param, 0, sizeof(TW_Sector));
1368 param->table_id = TW_UNIT_INFORMATION_TABLE_BASE + tw_dev->srb[request_id]->device->id;
1369 param->parameter_id = 7; /* unit flags */
1370 param->parameter_size_bytes = 1;
1371 param_value = tw_dev->alignment_physical_address[request_id];
1372 if (param_value == 0) {
1373 printk(KERN_WARNING "3w-xxxx: tw_scsiop_mode_sense(): Bad alignment physical address.\n");
1374 return 1;
1377 command_packet->byte8.param.sgl[0].address = param_value;
1378 command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
1379 command_que_value = tw_dev->command_packet_physical_address[request_id];
1380 if (command_que_value == 0) {
1381 printk(KERN_WARNING "3w-xxxx: tw_scsiop_mode_sense(): Bad command packet physical address.\n");
1382 return 1;
1385 /* Now try to post the command packet */
1386 tw_post_command_packet(tw_dev, request_id);
1388 return 0;
1389 } /* End tw_scsiop_mode_sense() */
1391 /* This function is called by the isr to complete a mode sense command */
1392 static int tw_scsiop_mode_sense_complete(TW_Device_Extension *tw_dev, int request_id)
1394 TW_Param *param;
1395 unsigned char *flags;
1396 unsigned char request_buffer[8];
1398 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_mode_sense_complete()\n");
1400 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
1401 if (param == NULL) {
1402 printk(KERN_WARNING "3w-xxxx: tw_scsiop_mode_sense_complete(): Bad alignment virtual address.\n");
1403 return 1;
1405 flags = (char *)&(param->data[0]);
1406 memset(request_buffer, 0, sizeof(request_buffer));
1408 request_buffer[0] = 0xf; /* mode data length */
1409 request_buffer[1] = 0; /* default medium type */
1410 request_buffer[2] = 0x10; /* dpo/fua support on */
1411 request_buffer[3] = 0; /* no block descriptors */
1412 request_buffer[4] = 0x8; /* caching page */
1413 request_buffer[5] = 0xa; /* page length */
1414 if (*flags & 0x1)
1415 request_buffer[6] = 0x5; /* WCE on, RCD on */
1416 else
1417 request_buffer[6] = 0x1; /* WCE off, RCD on */
1418 tw_transfer_internal(tw_dev, request_id, request_buffer,
1419 sizeof(request_buffer));
1421 return 0;
1422 } /* End tw_scsiop_mode_sense_complete() */
1424 /* This function handles scsi read_capacity commands */
1425 static int tw_scsiop_read_capacity(TW_Device_Extension *tw_dev, int request_id)
1427 TW_Param *param;
1428 TW_Command *command_packet;
1429 unsigned long command_que_value;
1430 unsigned long param_value;
1432 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity()\n");
1434 /* Initialize command packet */
1435 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
1437 if (command_packet == NULL) {
1438 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity(): Bad command packet virtual address.\n");
1439 return 1;
1441 memset(command_packet, 0, sizeof(TW_Sector));
1442 command_packet->opcode__sgloffset = TW_OPSGL_IN(2, TW_OP_GET_PARAM);
1443 command_packet->size = 4;
1444 command_packet->request_id = request_id;
1445 command_packet->unit__hostid = TW_UNITHOST_IN(0, tw_dev->srb[request_id]->device->id);
1446 command_packet->status = 0;
1447 command_packet->flags = 0;
1448 command_packet->byte6.block_count = 1;
1450 /* Now setup the param */
1451 if (tw_dev->alignment_virtual_address[request_id] == NULL) {
1452 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity(): Bad alignment virtual address.\n");
1453 return 1;
1455 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
1456 memset(param, 0, sizeof(TW_Sector));
1457 param->table_id = TW_UNIT_INFORMATION_TABLE_BASE +
1458 tw_dev->srb[request_id]->device->id;
1459 param->parameter_id = 4; /* unitcapacity parameter */
1460 param->parameter_size_bytes = 4;
1461 param_value = tw_dev->alignment_physical_address[request_id];
1462 if (param_value == 0) {
1463 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity(): Bad alignment physical address.\n");
1464 return 1;
1467 command_packet->byte8.param.sgl[0].address = param_value;
1468 command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
1469 command_que_value = tw_dev->command_packet_physical_address[request_id];
1470 if (command_que_value == 0) {
1471 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity(): Bad command packet physical address.\n");
1472 return 1;
1475 /* Now try to post the command to the board */
1476 tw_post_command_packet(tw_dev, request_id);
1478 return 0;
1479 } /* End tw_scsiop_read_capacity() */
1481 /* This function is called by the isr to complete a readcapacity command */
1482 static int tw_scsiop_read_capacity_complete(TW_Device_Extension *tw_dev, int request_id)
1484 unsigned char *param_data;
1485 u32 capacity;
1486 char buff[8];
1487 TW_Param *param;
1489 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity_complete()\n");
1491 memset(buff, 0, sizeof(buff));
1492 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
1493 if (param == NULL) {
1494 printk(KERN_WARNING "3w-xxxx: tw_scsiop_read_capacity_complete(): Bad alignment virtual address.\n");
1495 return 1;
1497 param_data = &(param->data[0]);
1499 capacity = (param_data[3] << 24) | (param_data[2] << 16) |
1500 (param_data[1] << 8) | param_data[0];
1502 /* Subtract one sector to fix get last sector ioctl */
1503 capacity -= 1;
1505 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity_complete(): Capacity = 0x%x.\n", capacity);
1507 /* Number of LBA's */
1508 buff[0] = (capacity >> 24);
1509 buff[1] = (capacity >> 16) & 0xff;
1510 buff[2] = (capacity >> 8) & 0xff;
1511 buff[3] = capacity & 0xff;
1513 /* Block size in bytes (512) */
1514 buff[4] = (TW_BLOCK_SIZE >> 24);
1515 buff[5] = (TW_BLOCK_SIZE >> 16) & 0xff;
1516 buff[6] = (TW_BLOCK_SIZE >> 8) & 0xff;
1517 buff[7] = TW_BLOCK_SIZE & 0xff;
1519 tw_transfer_internal(tw_dev, request_id, buff, sizeof(buff));
1521 return 0;
1522 } /* End tw_scsiop_read_capacity_complete() */
1524 /* This function handles scsi read or write commands */
1525 static int tw_scsiop_read_write(TW_Device_Extension *tw_dev, int request_id)
1527 TW_Command *command_packet;
1528 unsigned long command_que_value;
1529 u32 lba = 0x0, num_sectors = 0x0;
1530 int i, use_sg;
1531 struct scsi_cmnd *srb;
1532 struct scatterlist *sglist, *sg;
1534 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_write()\n");
1536 srb = tw_dev->srb[request_id];
1538 sglist = scsi_sglist(srb);
1539 if (!sglist) {
1540 printk(KERN_WARNING "3w-xxxx: tw_scsiop_read_write(): Request buffer NULL.\n");
1541 return 1;
1544 /* Initialize command packet */
1545 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
1546 if (command_packet == NULL) {
1547 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_write(): Bad command packet virtual address.\n");
1548 return 1;
1551 if (srb->cmnd[0] == READ_6 || srb->cmnd[0] == READ_10) {
1552 command_packet->opcode__sgloffset = TW_OPSGL_IN(3, TW_OP_READ);
1553 } else {
1554 command_packet->opcode__sgloffset = TW_OPSGL_IN(3, TW_OP_WRITE);
1557 command_packet->size = 3;
1558 command_packet->request_id = request_id;
1559 command_packet->unit__hostid = TW_UNITHOST_IN(0, srb->device->id);
1560 command_packet->status = 0;
1561 command_packet->flags = 0;
1563 if (srb->cmnd[0] == WRITE_10) {
1564 if ((srb->cmnd[1] & 0x8) || (srb->cmnd[1] & 0x10))
1565 command_packet->flags = 1;
1568 if (srb->cmnd[0] == READ_6 || srb->cmnd[0] == WRITE_6) {
1569 lba = ((u32)srb->cmnd[1] << 16) | ((u32)srb->cmnd[2] << 8) | (u32)srb->cmnd[3];
1570 num_sectors = (u32)srb->cmnd[4];
1571 } else {
1572 lba = ((u32)srb->cmnd[2] << 24) | ((u32)srb->cmnd[3] << 16) | ((u32)srb->cmnd[4] << 8) | (u32)srb->cmnd[5];
1573 num_sectors = (u32)srb->cmnd[8] | ((u32)srb->cmnd[7] << 8);
1576 /* Update sector statistic */
1577 tw_dev->sector_count = num_sectors;
1578 if (tw_dev->sector_count > tw_dev->max_sector_count)
1579 tw_dev->max_sector_count = tw_dev->sector_count;
1581 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_write(): lba = 0x%x num_sectors = 0x%x\n", lba, num_sectors);
1582 command_packet->byte8.io.lba = lba;
1583 command_packet->byte6.block_count = num_sectors;
1585 use_sg = tw_map_scsi_sg_data(tw_dev->tw_pci_dev, tw_dev->srb[request_id]);
1586 if (!use_sg)
1587 return 1;
1589 scsi_for_each_sg(tw_dev->srb[request_id], sg, use_sg, i) {
1590 command_packet->byte8.io.sgl[i].address = sg_dma_address(sg);
1591 command_packet->byte8.io.sgl[i].length = sg_dma_len(sg);
1592 command_packet->size+=2;
1595 /* Update SG statistics */
1596 tw_dev->sgl_entries = scsi_sg_count(tw_dev->srb[request_id]);
1597 if (tw_dev->sgl_entries > tw_dev->max_sgl_entries)
1598 tw_dev->max_sgl_entries = tw_dev->sgl_entries;
1600 command_que_value = tw_dev->command_packet_physical_address[request_id];
1601 if (command_que_value == 0) {
1602 dprintk(KERN_WARNING "3w-xxxx: tw_scsiop_read_write(): Bad command packet physical address.\n");
1603 return 1;
1606 /* Now try to post the command to the board */
1607 tw_post_command_packet(tw_dev, request_id);
1609 return 0;
1610 } /* End tw_scsiop_read_write() */
1612 /* This function will handle the request sense scsi command */
1613 static int tw_scsiop_request_sense(TW_Device_Extension *tw_dev, int request_id)
1615 char request_buffer[18];
1617 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_request_sense()\n");
1619 memset(request_buffer, 0, sizeof(request_buffer));
1620 request_buffer[0] = 0x70; /* Immediate fixed format */
1621 request_buffer[7] = 10; /* minimum size per SPC: 18 bytes */
1622 /* leave all other fields zero, giving effectively NO_SENSE return */
1623 tw_transfer_internal(tw_dev, request_id, request_buffer,
1624 sizeof(request_buffer));
1626 tw_dev->state[request_id] = TW_S_COMPLETED;
1627 tw_state_request_finish(tw_dev, request_id);
1629 /* If we got a request_sense, we probably want a reset, return error */
1630 tw_dev->srb[request_id]->result = (DID_ERROR << 16);
1631 tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
1633 return 0;
1634 } /* End tw_scsiop_request_sense() */
1636 /* This function will handle synchronize cache scsi command */
1637 static int tw_scsiop_synchronize_cache(TW_Device_Extension *tw_dev, int request_id)
1639 TW_Command *command_packet;
1640 unsigned long command_que_value;
1642 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_synchronize_cache()\n");
1644 /* Send firmware flush command for this unit */
1645 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
1646 if (command_packet == NULL) {
1647 printk(KERN_WARNING "3w-xxxx: tw_scsiop_synchronize_cache(): Bad command packet virtual address.\n");
1648 return 1;
1651 /* Setup the command packet */
1652 memset(command_packet, 0, sizeof(TW_Sector));
1653 command_packet->opcode__sgloffset = TW_OPSGL_IN(0, TW_OP_FLUSH_CACHE);
1654 command_packet->size = 2;
1655 command_packet->request_id = request_id;
1656 command_packet->unit__hostid = TW_UNITHOST_IN(0, tw_dev->srb[request_id]->device->id);
1657 command_packet->status = 0;
1658 command_packet->flags = 0;
1659 command_packet->byte6.parameter_count = 1;
1660 command_que_value = tw_dev->command_packet_physical_address[request_id];
1661 if (command_que_value == 0) {
1662 printk(KERN_WARNING "3w-xxxx: tw_scsiop_synchronize_cache(): Bad command packet physical address.\n");
1663 return 1;
1666 /* Now try to post the command packet */
1667 tw_post_command_packet(tw_dev, request_id);
1669 return 0;
1670 } /* End tw_scsiop_synchronize_cache() */
1672 /* This function will handle test unit ready scsi command */
1673 static int tw_scsiop_test_unit_ready(TW_Device_Extension *tw_dev, int request_id)
1675 TW_Param *param;
1676 TW_Command *command_packet;
1677 unsigned long command_que_value;
1678 unsigned long param_value;
1680 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_test_unit_ready()\n");
1682 /* Initialize command packet */
1683 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
1684 if (command_packet == NULL) {
1685 printk(KERN_WARNING "3w-xxxx: tw_scsiop_test_unit_ready(): Bad command packet virtual address.\n");
1686 return 1;
1688 memset(command_packet, 0, sizeof(TW_Sector));
1689 command_packet->opcode__sgloffset = TW_OPSGL_IN(2, TW_OP_GET_PARAM);
1690 command_packet->size = 4;
1691 command_packet->request_id = request_id;
1692 command_packet->status = 0;
1693 command_packet->flags = 0;
1694 command_packet->byte6.parameter_count = 1;
1696 /* Now setup the param */
1697 if (tw_dev->alignment_virtual_address[request_id] == NULL) {
1698 printk(KERN_WARNING "3w-xxxx: tw_scsiop_test_unit_ready(): Bad alignment virtual address.\n");
1699 return 1;
1701 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
1702 memset(param, 0, sizeof(TW_Sector));
1703 param->table_id = 3; /* unit summary table */
1704 param->parameter_id = 3; /* unitsstatus parameter */
1705 param->parameter_size_bytes = TW_MAX_UNITS;
1706 param_value = tw_dev->alignment_physical_address[request_id];
1707 if (param_value == 0) {
1708 printk(KERN_WARNING "3w-xxxx: tw_scsiop_test_unit_ready(): Bad alignment physical address.\n");
1709 return 1;
1712 command_packet->byte8.param.sgl[0].address = param_value;
1713 command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
1714 command_que_value = tw_dev->command_packet_physical_address[request_id];
1715 if (command_que_value == 0) {
1716 printk(KERN_WARNING "3w-xxxx: tw_scsiop_test_unit_ready(): Bad command packet physical address.\n");
1717 return 1;
1720 /* Now try to post the command packet */
1721 tw_post_command_packet(tw_dev, request_id);
1723 return 0;
1724 } /* End tw_scsiop_test_unit_ready() */
1726 /* This function is called by the isr to complete a testunitready command */
1727 static int tw_scsiop_test_unit_ready_complete(TW_Device_Extension *tw_dev, int request_id)
1729 unsigned char *is_unit_present;
1730 TW_Param *param;
1732 dprintk(KERN_WARNING "3w-xxxx: tw_scsiop_test_unit_ready_complete()\n");
1734 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
1735 if (param == NULL) {
1736 printk(KERN_WARNING "3w-xxxx: tw_scsiop_test_unit_ready_complete(): Bad alignment virtual address.\n");
1737 return 1;
1739 is_unit_present = &(param->data[0]);
1741 if (is_unit_present[tw_dev->srb[request_id]->device->id] & TW_UNIT_ONLINE) {
1742 tw_dev->is_unit_present[tw_dev->srb[request_id]->device->id] = 1;
1743 } else {
1744 tw_dev->is_unit_present[tw_dev->srb[request_id]->device->id] = 0;
1745 tw_dev->srb[request_id]->result = (DID_BAD_TARGET << 16);
1746 return TW_ISR_DONT_RESULT;
1749 return 0;
1750 } /* End tw_scsiop_test_unit_ready_complete() */
1752 /* This is the main scsi queue function to handle scsi opcodes */
1753 static int tw_scsi_queue(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
1755 unsigned char *command = SCpnt->cmnd;
1756 int request_id = 0;
1757 int retval = 1;
1758 TW_Device_Extension *tw_dev = (TW_Device_Extension *)SCpnt->device->host->hostdata;
1760 /* If we are resetting due to timed out ioctl, report as busy */
1761 if (test_bit(TW_IN_RESET, &tw_dev->flags))
1762 return SCSI_MLQUEUE_HOST_BUSY;
1764 /* Save done function into Scsi_Cmnd struct */
1765 SCpnt->scsi_done = done;
1767 /* Queue the command and get a request id */
1768 tw_state_request_start(tw_dev, &request_id);
1770 /* Save the scsi command for use by the ISR */
1771 tw_dev->srb[request_id] = SCpnt;
1773 /* Initialize phase to zero */
1774 SCpnt->SCp.phase = TW_PHASE_INITIAL;
1776 switch (*command) {
1777 case READ_10:
1778 case READ_6:
1779 case WRITE_10:
1780 case WRITE_6:
1781 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught READ/WRITE.\n");
1782 retval = tw_scsiop_read_write(tw_dev, request_id);
1783 break;
1784 case TEST_UNIT_READY:
1785 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught TEST_UNIT_READY.\n");
1786 retval = tw_scsiop_test_unit_ready(tw_dev, request_id);
1787 break;
1788 case INQUIRY:
1789 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught INQUIRY.\n");
1790 retval = tw_scsiop_inquiry(tw_dev, request_id);
1791 break;
1792 case READ_CAPACITY:
1793 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught READ_CAPACITY.\n");
1794 retval = tw_scsiop_read_capacity(tw_dev, request_id);
1795 break;
1796 case REQUEST_SENSE:
1797 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught REQUEST_SENSE.\n");
1798 retval = tw_scsiop_request_sense(tw_dev, request_id);
1799 break;
1800 case MODE_SENSE:
1801 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught MODE_SENSE.\n");
1802 retval = tw_scsiop_mode_sense(tw_dev, request_id);
1803 break;
1804 case SYNCHRONIZE_CACHE:
1805 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught SYNCHRONIZE_CACHE.\n");
1806 retval = tw_scsiop_synchronize_cache(tw_dev, request_id);
1807 break;
1808 case TW_IOCTL:
1809 printk(KERN_WARNING "3w-xxxx: SCSI_IOCTL_SEND_COMMAND deprecated, please update your 3ware tools.\n");
1810 break;
1811 default:
1812 printk(KERN_NOTICE "3w-xxxx: scsi%d: Unknown scsi opcode: 0x%x\n", tw_dev->host->host_no, *command);
1813 tw_dev->state[request_id] = TW_S_COMPLETED;
1814 tw_state_request_finish(tw_dev, request_id);
1815 SCpnt->result = (DID_BAD_TARGET << 16);
1816 done(SCpnt);
1817 retval = 0;
1819 if (retval) {
1820 tw_dev->state[request_id] = TW_S_COMPLETED;
1821 tw_state_request_finish(tw_dev, request_id);
1822 SCpnt->result = (DID_ERROR << 16);
1823 done(SCpnt);
1824 retval = 0;
1826 return retval;
1827 } /* End tw_scsi_queue() */
1829 /* This function is the interrupt service routine */
1830 static irqreturn_t tw_interrupt(int irq, void *dev_instance)
1832 int request_id;
1833 u32 status_reg_value;
1834 TW_Device_Extension *tw_dev = (TW_Device_Extension *)dev_instance;
1835 TW_Response_Queue response_que;
1836 int error = 0, retval = 0;
1837 TW_Command *command_packet;
1838 int handled = 0;
1840 /* Get the host lock for io completions */
1841 spin_lock(tw_dev->host->host_lock);
1843 /* Read the registers */
1844 status_reg_value = inl(TW_STATUS_REG_ADDR(tw_dev));
1846 /* Check if this is our interrupt, otherwise bail */
1847 if (!(status_reg_value & TW_STATUS_VALID_INTERRUPT))
1848 goto tw_interrupt_bail;
1850 handled = 1;
1852 /* If we are resetting, bail */
1853 if (test_bit(TW_IN_RESET, &tw_dev->flags))
1854 goto tw_interrupt_bail;
1856 /* Check controller for errors */
1857 if (tw_check_bits(status_reg_value)) {
1858 dprintk(KERN_WARNING "3w-xxxx: tw_interrupt(): Unexpected bits.\n");
1859 if (tw_decode_bits(tw_dev, status_reg_value, 1)) {
1860 TW_CLEAR_ALL_INTERRUPTS(tw_dev);
1861 goto tw_interrupt_bail;
1865 /* Handle host interrupt */
1866 if (status_reg_value & TW_STATUS_HOST_INTERRUPT) {
1867 dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): Received host interrupt.\n");
1868 TW_CLEAR_HOST_INTERRUPT(tw_dev);
1871 /* Handle attention interrupt */
1872 if (status_reg_value & TW_STATUS_ATTENTION_INTERRUPT) {
1873 dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): Received attention interrupt.\n");
1874 TW_CLEAR_ATTENTION_INTERRUPT(tw_dev);
1875 tw_state_request_start(tw_dev, &request_id);
1876 error = tw_aen_read_queue(tw_dev, request_id);
1877 if (error) {
1878 printk(KERN_WARNING "3w-xxxx: scsi%d: Error reading aen queue.\n", tw_dev->host->host_no);
1879 tw_dev->state[request_id] = TW_S_COMPLETED;
1880 tw_state_request_finish(tw_dev, request_id);
1884 /* Handle command interrupt */
1885 if (status_reg_value & TW_STATUS_COMMAND_INTERRUPT) {
1886 /* Drain as many pending commands as we can */
1887 while (tw_dev->pending_request_count > 0) {
1888 request_id = tw_dev->pending_queue[tw_dev->pending_head];
1889 if (tw_dev->state[request_id] != TW_S_PENDING) {
1890 printk(KERN_WARNING "3w-xxxx: scsi%d: Found request id that wasn't pending.\n", tw_dev->host->host_no);
1891 break;
1893 if (tw_post_command_packet(tw_dev, request_id)==0) {
1894 if (tw_dev->pending_head == TW_Q_LENGTH-1) {
1895 tw_dev->pending_head = TW_Q_START;
1896 } else {
1897 tw_dev->pending_head = tw_dev->pending_head + 1;
1899 tw_dev->pending_request_count--;
1900 } else {
1901 /* If we get here, we will continue re-posting on the next command interrupt */
1902 break;
1905 /* If there are no more pending requests, we mask command interrupt */
1906 if (tw_dev->pending_request_count == 0)
1907 TW_MASK_COMMAND_INTERRUPT(tw_dev);
1910 /* Handle response interrupt */
1911 if (status_reg_value & TW_STATUS_RESPONSE_INTERRUPT) {
1912 /* Drain the response queue from the board */
1913 while ((status_reg_value & TW_STATUS_RESPONSE_QUEUE_EMPTY) == 0) {
1914 /* Read response queue register */
1915 response_que.value = inl(TW_RESPONSE_QUEUE_REG_ADDR(tw_dev));
1916 request_id = TW_RESID_OUT(response_que.response_id);
1917 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
1918 error = 0;
1920 /* Check for bad response */
1921 if (command_packet->status != 0) {
1922 /* If internal command, don't error, don't fill sense */
1923 if (tw_dev->srb[request_id] == NULL) {
1924 tw_decode_sense(tw_dev, request_id, 0);
1925 } else {
1926 error = tw_decode_sense(tw_dev, request_id, 1);
1930 /* Check for correct state */
1931 if (tw_dev->state[request_id] != TW_S_POSTED) {
1932 if (tw_dev->srb[request_id] != NULL) {
1933 printk(KERN_WARNING "3w-xxxx: scsi%d: Received a request id that wasn't posted.\n", tw_dev->host->host_no);
1934 error = 1;
1938 dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): Response queue request id: %d.\n", request_id);
1940 /* Check for internal command completion */
1941 if (tw_dev->srb[request_id] == NULL) {
1942 dprintk(KERN_WARNING "3w-xxxx: tw_interrupt(): Found internally posted command.\n");
1943 /* Check for chrdev ioctl completion */
1944 if (request_id != tw_dev->chrdev_request_id) {
1945 retval = tw_aen_complete(tw_dev, request_id);
1946 if (retval) {
1947 printk(KERN_WARNING "3w-xxxx: scsi%d: Error completing aen.\n", tw_dev->host->host_no);
1949 } else {
1950 tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE;
1951 wake_up(&tw_dev->ioctl_wqueue);
1953 } else {
1954 switch (tw_dev->srb[request_id]->cmnd[0]) {
1955 case READ_10:
1956 case READ_6:
1957 dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught READ_10/READ_6\n");
1958 break;
1959 case WRITE_10:
1960 case WRITE_6:
1961 dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught WRITE_10/WRITE_6\n");
1962 break;
1963 case TEST_UNIT_READY:
1964 dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught TEST_UNIT_READY\n");
1965 error = tw_scsiop_test_unit_ready_complete(tw_dev, request_id);
1966 break;
1967 case INQUIRY:
1968 dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught INQUIRY\n");
1969 error = tw_scsiop_inquiry_complete(tw_dev, request_id);
1970 break;
1971 case READ_CAPACITY:
1972 dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught READ_CAPACITY\n");
1973 error = tw_scsiop_read_capacity_complete(tw_dev, request_id);
1974 break;
1975 case MODE_SENSE:
1976 dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught MODE_SENSE\n");
1977 error = tw_scsiop_mode_sense_complete(tw_dev, request_id);
1978 break;
1979 case SYNCHRONIZE_CACHE:
1980 dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught SYNCHRONIZE_CACHE\n");
1981 break;
1982 default:
1983 printk(KERN_WARNING "3w-xxxx: case slip in tw_interrupt()\n");
1984 error = 1;
1987 /* If no error command was a success */
1988 if (error == 0) {
1989 tw_dev->srb[request_id]->result = (DID_OK << 16);
1992 /* If error, command failed */
1993 if (error == 1) {
1994 /* Ask for a host reset */
1995 tw_dev->srb[request_id]->result = (DID_OK << 16) | (CHECK_CONDITION << 1);
1998 /* Now complete the io */
1999 if ((error != TW_ISR_DONT_COMPLETE)) {
2000 tw_dev->state[request_id] = TW_S_COMPLETED;
2001 tw_state_request_finish(tw_dev, request_id);
2002 tw_dev->posted_request_count--;
2003 tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
2005 tw_unmap_scsi_data(tw_dev->tw_pci_dev, tw_dev->srb[request_id]);
2009 /* Check for valid status after each drain */
2010 status_reg_value = inl(TW_STATUS_REG_ADDR(tw_dev));
2011 if (tw_check_bits(status_reg_value)) {
2012 dprintk(KERN_WARNING "3w-xxxx: tw_interrupt(): Unexpected bits.\n");
2013 if (tw_decode_bits(tw_dev, status_reg_value, 1)) {
2014 TW_CLEAR_ALL_INTERRUPTS(tw_dev);
2015 goto tw_interrupt_bail;
2021 tw_interrupt_bail:
2022 spin_unlock(tw_dev->host->host_lock);
2023 return IRQ_RETVAL(handled);
2024 } /* End tw_interrupt() */
2026 /* This function tells the controller to shut down */
2027 static void __tw_shutdown(TW_Device_Extension *tw_dev)
2029 /* Disable interrupts */
2030 TW_DISABLE_INTERRUPTS(tw_dev);
2032 /* Free up the IRQ */
2033 free_irq(tw_dev->tw_pci_dev->irq, tw_dev);
2035 printk(KERN_WARNING "3w-xxxx: Shutting down host %d.\n", tw_dev->host->host_no);
2037 /* Tell the card we are shutting down */
2038 if (tw_initconnection(tw_dev, 1)) {
2039 printk(KERN_WARNING "3w-xxxx: Connection shutdown failed.\n");
2040 } else {
2041 printk(KERN_WARNING "3w-xxxx: Shutdown complete.\n");
2044 /* Clear all interrupts just before exit */
2045 TW_ENABLE_AND_CLEAR_INTERRUPTS(tw_dev);
2046 } /* End __tw_shutdown() */
2048 /* Wrapper for __tw_shutdown */
2049 static void tw_shutdown(struct pci_dev *pdev)
2051 struct Scsi_Host *host = pci_get_drvdata(pdev);
2052 TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata;
2054 __tw_shutdown(tw_dev);
2055 } /* End tw_shutdown() */
2057 /* This function gets called when a disk is coming online */
2058 static int tw_slave_configure(struct scsi_device *sdev)
2060 /* Force 60 second timeout */
2061 blk_queue_rq_timeout(sdev->request_queue, 60 * HZ);
2063 return 0;
2064 } /* End tw_slave_configure() */
2066 static struct scsi_host_template driver_template = {
2067 .module = THIS_MODULE,
2068 .name = "3ware Storage Controller",
2069 .queuecommand = tw_scsi_queue,
2070 .eh_host_reset_handler = tw_scsi_eh_reset,
2071 .bios_param = tw_scsi_biosparam,
2072 .change_queue_depth = tw_change_queue_depth,
2073 .can_queue = TW_Q_LENGTH-2,
2074 .slave_configure = tw_slave_configure,
2075 .this_id = -1,
2076 .sg_tablesize = TW_MAX_SGL_LENGTH,
2077 .max_sectors = TW_MAX_SECTORS,
2078 .cmd_per_lun = TW_MAX_CMDS_PER_LUN,
2079 .use_clustering = ENABLE_CLUSTERING,
2080 .shost_attrs = tw_host_attrs,
2081 .emulated = 1
2084 /* This function will probe and initialize a card */
2085 static int __devinit tw_probe(struct pci_dev *pdev, const struct pci_device_id *dev_id)
2087 struct Scsi_Host *host = NULL;
2088 TW_Device_Extension *tw_dev;
2089 int retval = -ENODEV;
2091 retval = pci_enable_device(pdev);
2092 if (retval) {
2093 printk(KERN_WARNING "3w-xxxx: Failed to enable pci device.");
2094 goto out_disable_device;
2097 pci_set_master(pdev);
2099 retval = pci_set_dma_mask(pdev, TW_DMA_MASK);
2100 if (retval) {
2101 printk(KERN_WARNING "3w-xxxx: Failed to set dma mask.");
2102 goto out_disable_device;
2105 host = scsi_host_alloc(&driver_template, sizeof(TW_Device_Extension));
2106 if (!host) {
2107 printk(KERN_WARNING "3w-xxxx: Failed to allocate memory for device extension.");
2108 retval = -ENOMEM;
2109 goto out_disable_device;
2111 tw_dev = (TW_Device_Extension *)host->hostdata;
2113 /* Save values to device extension */
2114 tw_dev->host = host;
2115 tw_dev->tw_pci_dev = pdev;
2117 if (tw_initialize_device_extension(tw_dev)) {
2118 printk(KERN_WARNING "3w-xxxx: Failed to initialize device extension.");
2119 goto out_free_device_extension;
2122 /* Request IO regions */
2123 retval = pci_request_regions(pdev, "3w-xxxx");
2124 if (retval) {
2125 printk(KERN_WARNING "3w-xxxx: Failed to get mem region.");
2126 goto out_free_device_extension;
2129 /* Save base address */
2130 tw_dev->base_addr = pci_resource_start(pdev, 0);
2131 if (!tw_dev->base_addr) {
2132 printk(KERN_WARNING "3w-xxxx: Failed to get io address.");
2133 goto out_release_mem_region;
2136 /* Disable interrupts on the card */
2137 TW_DISABLE_INTERRUPTS(tw_dev);
2139 /* Initialize the card */
2140 if (tw_reset_sequence(tw_dev))
2141 goto out_release_mem_region;
2143 /* Set host specific parameters */
2144 host->max_id = TW_MAX_UNITS;
2145 host->max_cmd_len = TW_MAX_CDB_LEN;
2147 /* Luns and channels aren't supported by adapter */
2148 host->max_lun = 0;
2149 host->max_channel = 0;
2151 /* Register the card with the kernel SCSI layer */
2152 retval = scsi_add_host(host, &pdev->dev);
2153 if (retval) {
2154 printk(KERN_WARNING "3w-xxxx: scsi add host failed");
2155 goto out_release_mem_region;
2158 pci_set_drvdata(pdev, host);
2160 printk(KERN_WARNING "3w-xxxx: scsi%d: Found a 3ware Storage Controller at 0x%x, IRQ: %d.\n", host->host_no, tw_dev->base_addr, pdev->irq);
2162 /* Now setup the interrupt handler */
2163 retval = request_irq(pdev->irq, tw_interrupt, IRQF_SHARED, "3w-xxxx", tw_dev);
2164 if (retval) {
2165 printk(KERN_WARNING "3w-xxxx: Error requesting IRQ.");
2166 goto out_remove_host;
2169 tw_device_extension_list[tw_device_extension_count] = tw_dev;
2170 tw_device_extension_count++;
2172 /* Re-enable interrupts on the card */
2173 TW_ENABLE_AND_CLEAR_INTERRUPTS(tw_dev);
2175 /* Finally, scan the host */
2176 scsi_scan_host(host);
2178 if (twe_major == -1) {
2179 if ((twe_major = register_chrdev (0, "twe", &tw_fops)) < 0)
2180 printk(KERN_WARNING "3w-xxxx: Failed to register character device.");
2182 return 0;
2184 out_remove_host:
2185 scsi_remove_host(host);
2186 out_release_mem_region:
2187 pci_release_regions(pdev);
2188 out_free_device_extension:
2189 tw_free_device_extension(tw_dev);
2190 scsi_host_put(host);
2191 out_disable_device:
2192 pci_disable_device(pdev);
2194 return retval;
2195 } /* End tw_probe() */
2197 /* This function is called to remove a device */
2198 static void tw_remove(struct pci_dev *pdev)
2200 struct Scsi_Host *host = pci_get_drvdata(pdev);
2201 TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata;
2203 scsi_remove_host(tw_dev->host);
2205 /* Unregister character device */
2206 if (twe_major >= 0) {
2207 unregister_chrdev(twe_major, "twe");
2208 twe_major = -1;
2211 /* Shutdown the card */
2212 __tw_shutdown(tw_dev);
2214 /* Free up the mem region */
2215 pci_release_regions(pdev);
2217 /* Free up device extension resources */
2218 tw_free_device_extension(tw_dev);
2220 scsi_host_put(tw_dev->host);
2221 pci_disable_device(pdev);
2222 tw_device_extension_count--;
2223 } /* End tw_remove() */
2225 /* PCI Devices supported by this driver */
2226 static struct pci_device_id tw_pci_tbl[] __devinitdata = {
2227 { PCI_VENDOR_ID_3WARE, PCI_DEVICE_ID_3WARE_1000,
2228 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
2229 { PCI_VENDOR_ID_3WARE, PCI_DEVICE_ID_3WARE_7000,
2230 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
2233 MODULE_DEVICE_TABLE(pci, tw_pci_tbl);
2235 /* pci_driver initializer */
2236 static struct pci_driver tw_driver = {
2237 .name = "3w-xxxx",
2238 .id_table = tw_pci_tbl,
2239 .probe = tw_probe,
2240 .remove = tw_remove,
2241 .shutdown = tw_shutdown,
2244 /* This function is called on driver initialization */
2245 static int __init tw_init(void)
2247 printk(KERN_WARNING "3ware Storage Controller device driver for Linux v%s.\n", TW_DRIVER_VERSION);
2249 return pci_register_driver(&tw_driver);
2250 } /* End tw_init() */
2252 /* This function is called on driver exit */
2253 static void __exit tw_exit(void)
2255 pci_unregister_driver(&tw_driver);
2256 } /* End tw_exit() */
2258 module_init(tw_init);
2259 module_exit(tw_exit);