1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199#include <linux/module.h>
200#include <linux/reboot.h>
201#include <linux/smp_lock.h>
202#include <linux/spinlock.h>
203#include <linux/interrupt.h>
204#include <linux/moduleparam.h>
205#include <linux/errno.h>
206#include <linux/types.h>
207#include <linux/delay.h>
208#include <linux/pci.h>
209#include <linux/time.h>
210#include <linux/mutex.h>
211#include <asm/io.h>
212#include <asm/irq.h>
213#include <asm/uaccess.h>
214#include <scsi/scsi.h>
215#include <scsi/scsi_host.h>
216#include <scsi/scsi_tcq.h>
217#include <scsi/scsi_cmnd.h>
218#include "3w-xxxx.h"
219
220
221#define TW_DRIVER_VERSION "1.26.02.002"
222static TW_Device_Extension *tw_device_extension_list[TW_MAX_SLOT];
223static int tw_device_extension_count = 0;
224static int twe_major = -1;
225
226
227MODULE_AUTHOR("AMCC");
228MODULE_DESCRIPTION("3ware Storage Controller Linux Driver");
229MODULE_LICENSE("GPL");
230MODULE_VERSION(TW_DRIVER_VERSION);
231
232
233static int tw_reset_device_extension(TW_Device_Extension *tw_dev);
234
235
236
237
238static int tw_check_bits(u32 status_reg_value)
239{
240 if ((status_reg_value & TW_STATUS_EXPECTED_BITS) != TW_STATUS_EXPECTED_BITS) {
241 dprintk(KERN_WARNING "3w-xxxx: tw_check_bits(): No expected bits (0x%x).\n", status_reg_value);
242 return 1;
243 }
244 if ((status_reg_value & TW_STATUS_UNEXPECTED_BITS) != 0) {
245 dprintk(KERN_WARNING "3w-xxxx: tw_check_bits(): Found unexpected bits (0x%x).\n", status_reg_value);
246 return 1;
247 }
248
249 return 0;
250}
251
252
253static int tw_decode_bits(TW_Device_Extension *tw_dev, u32 status_reg_value, int print_host)
254{
255 char host[16];
256
257 dprintk(KERN_WARNING "3w-xxxx: tw_decode_bits()\n");
258
259 if (print_host)
260 sprintf(host, " scsi%d:", tw_dev->host->host_no);
261 else
262 host[0] = '\0';
263
264 if (status_reg_value & TW_STATUS_PCI_PARITY_ERROR) {
265 printk(KERN_WARNING "3w-xxxx:%s PCI Parity Error: clearing.\n", host);
266 outl(TW_CONTROL_CLEAR_PARITY_ERROR, TW_CONTROL_REG_ADDR(tw_dev));
267 }
268
269 if (status_reg_value & TW_STATUS_PCI_ABORT) {
270 printk(KERN_WARNING "3w-xxxx:%s PCI Abort: clearing.\n", host);
271 outl(TW_CONTROL_CLEAR_PCI_ABORT, TW_CONTROL_REG_ADDR(tw_dev));
272 pci_write_config_word(tw_dev->tw_pci_dev, PCI_STATUS, TW_PCI_CLEAR_PCI_ABORT);
273 }
274
275 if (status_reg_value & TW_STATUS_QUEUE_ERROR) {
276 printk(KERN_WARNING "3w-xxxx:%s Controller Queue Error: clearing.\n", host);
277 outl(TW_CONTROL_CLEAR_QUEUE_ERROR, TW_CONTROL_REG_ADDR(tw_dev));
278 }
279
280 if (status_reg_value & TW_STATUS_SBUF_WRITE_ERROR) {
281 printk(KERN_WARNING "3w-xxxx:%s SBUF Write Error: clearing.\n", host);
282 outl(TW_CONTROL_CLEAR_SBUF_WRITE_ERROR, TW_CONTROL_REG_ADDR(tw_dev));
283 }
284
285 if (status_reg_value & TW_STATUS_MICROCONTROLLER_ERROR) {
286 if (tw_dev->reset_print == 0) {
287 printk(KERN_WARNING "3w-xxxx:%s Microcontroller Error: clearing.\n", host);
288 tw_dev->reset_print = 1;
289 }
290 return 1;
291 }
292
293 return 0;
294}
295
296
297static int tw_poll_status(TW_Device_Extension *tw_dev, u32 flag, int seconds)
298{
299 u32 status_reg_value;
300 unsigned long before;
301 int retval = 1;
302
303 status_reg_value = inl(TW_STATUS_REG_ADDR(tw_dev));
304 before = jiffies;
305
306 if (tw_check_bits(status_reg_value))
307 tw_decode_bits(tw_dev, status_reg_value, 0);
308
309 while ((status_reg_value & flag) != flag) {
310 status_reg_value = inl(TW_STATUS_REG_ADDR(tw_dev));
311
312 if (tw_check_bits(status_reg_value))
313 tw_decode_bits(tw_dev, status_reg_value, 0);
314
315 if (time_after(jiffies, before + HZ * seconds))
316 goto out;
317
318 msleep(50);
319 }
320 retval = 0;
321out:
322 return retval;
323}
324
325
326static int tw_poll_status_gone(TW_Device_Extension *tw_dev, u32 flag, int seconds)
327{
328 u32 status_reg_value;
329 unsigned long before;
330 int retval = 1;
331
332 status_reg_value = inl(TW_STATUS_REG_ADDR(tw_dev));
333 before = jiffies;
334
335 if (tw_check_bits(status_reg_value))
336 tw_decode_bits(tw_dev, status_reg_value, 0);
337
338 while ((status_reg_value & flag) != 0) {
339 status_reg_value = inl(TW_STATUS_REG_ADDR(tw_dev));
340
341 if (tw_check_bits(status_reg_value))
342 tw_decode_bits(tw_dev, status_reg_value, 0);
343
344 if (time_after(jiffies, before + HZ * seconds))
345 goto out;
346
347 msleep(50);
348 }
349 retval = 0;
350out:
351 return retval;
352}
353
354
355static int tw_post_command_packet(TW_Device_Extension *tw_dev, int request_id)
356{
357 u32 status_reg_value;
358 unsigned long command_que_value;
359
360 dprintk(KERN_NOTICE "3w-xxxx: tw_post_command_packet()\n");
361 command_que_value = tw_dev->command_packet_physical_address[request_id];
362 status_reg_value = inl(TW_STATUS_REG_ADDR(tw_dev));
363
364 if (tw_check_bits(status_reg_value)) {
365 dprintk(KERN_WARNING "3w-xxxx: tw_post_command_packet(): Unexpected bits.\n");
366 tw_decode_bits(tw_dev, status_reg_value, 1);
367 }
368
369 if ((status_reg_value & TW_STATUS_COMMAND_QUEUE_FULL) == 0) {
370
371 outl(command_que_value, TW_COMMAND_QUEUE_REG_ADDR(tw_dev));
372 tw_dev->state[request_id] = TW_S_POSTED;
373 tw_dev->posted_request_count++;
374 if (tw_dev->posted_request_count > tw_dev->max_posted_request_count) {
375 tw_dev->max_posted_request_count = tw_dev->posted_request_count;
376 }
377 } else {
378
379 if (tw_dev->state[request_id] != TW_S_PENDING) {
380 tw_dev->state[request_id] = TW_S_PENDING;
381 tw_dev->pending_request_count++;
382 if (tw_dev->pending_request_count > tw_dev->max_pending_request_count) {
383 tw_dev->max_pending_request_count = tw_dev->pending_request_count;
384 }
385 tw_dev->pending_queue[tw_dev->pending_tail] = request_id;
386 if (tw_dev->pending_tail == TW_Q_LENGTH-1) {
387 tw_dev->pending_tail = TW_Q_START;
388 } else {
389 tw_dev->pending_tail = tw_dev->pending_tail + 1;
390 }
391 }
392 TW_UNMASK_COMMAND_INTERRUPT(tw_dev);
393 return 1;
394 }
395 return 0;
396}
397
398
399static int tw_decode_sense(TW_Device_Extension *tw_dev, int request_id, int fill_sense)
400{
401 int i;
402 TW_Command *command;
403
404 dprintk(KERN_WARNING "3w-xxxx: tw_decode_sense()\n");
405 command = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
406
407 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));
408
409
410 if (fill_sense) {
411 if ((command->status == 0xc7) || (command->status == 0xcb)) {
412 for (i = 0; i < ARRAY_SIZE(tw_sense_table); i++) {
413 if (command->flags == tw_sense_table[i][0]) {
414
415
416 tw_dev->srb[request_id]->sense_buffer[0] = (0x1 << 7 | 0x70);
417
418
419 tw_dev->srb[request_id]->sense_buffer[2] = tw_sense_table[i][1];
420
421
422 tw_dev->srb[request_id]->sense_buffer[7] = 0xa;
423
424
425 tw_dev->srb[request_id]->sense_buffer[12] = tw_sense_table[i][2];
426
427
428 tw_dev->srb[request_id]->sense_buffer[13] = tw_sense_table[i][3];
429
430 tw_dev->srb[request_id]->result = (DID_OK << 16) | (CHECK_CONDITION << 1);
431 return TW_ISR_DONT_RESULT;
432 }
433 }
434 }
435
436
437 return 1;
438 }
439
440 return 0;
441}
442
443
444static int tw_check_errors(TW_Device_Extension *tw_dev)
445{
446 u32 status_reg_value;
447
448 status_reg_value = inl(TW_STATUS_REG_ADDR(tw_dev));
449
450 if (TW_STATUS_ERRORS(status_reg_value) || tw_check_bits(status_reg_value)) {
451 tw_decode_bits(tw_dev, status_reg_value, 0);
452 return 1;
453 }
454
455 return 0;
456}
457
458
459static void tw_empty_response_que(TW_Device_Extension *tw_dev)
460{
461 u32 status_reg_value, response_que_value;
462
463 status_reg_value = inl(TW_STATUS_REG_ADDR(tw_dev));
464
465 while ((status_reg_value & TW_STATUS_RESPONSE_QUEUE_EMPTY) == 0) {
466 response_que_value = inl(TW_RESPONSE_QUEUE_REG_ADDR(tw_dev));
467 status_reg_value = inl(TW_STATUS_REG_ADDR(tw_dev));
468 }
469}
470
471
472static void tw_state_request_finish(TW_Device_Extension *tw_dev, int request_id)
473{
474 tw_dev->free_queue[tw_dev->free_tail] = request_id;
475 tw_dev->state[request_id] = TW_S_FINISHED;
476 tw_dev->free_tail = (tw_dev->free_tail + 1) % TW_Q_LENGTH;
477}
478
479
480static void tw_state_request_start(TW_Device_Extension *tw_dev, int *request_id)
481{
482 *request_id = tw_dev->free_queue[tw_dev->free_head];
483 tw_dev->free_head = (tw_dev->free_head + 1) % TW_Q_LENGTH;
484 tw_dev->state[*request_id] = TW_S_STARTED;
485}
486
487
488static ssize_t tw_show_stats(struct device *dev, struct device_attribute *attr,
489 char *buf)
490{
491 struct Scsi_Host *host = class_to_shost(dev);
492 TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata;
493 unsigned long flags = 0;
494 ssize_t len;
495
496 spin_lock_irqsave(tw_dev->host->host_lock, flags);
497 len = snprintf(buf, PAGE_SIZE, "3w-xxxx Driver version: %s\n"
498 "Current commands posted: %4d\n"
499 "Max commands posted: %4d\n"
500 "Current pending commands: %4d\n"
501 "Max pending commands: %4d\n"
502 "Last sgl length: %4d\n"
503 "Max sgl length: %4d\n"
504 "Last sector count: %4d\n"
505 "Max sector count: %4d\n"
506 "SCSI Host Resets: %4d\n"
507 "AEN's: %4d\n",
508 TW_DRIVER_VERSION,
509 tw_dev->posted_request_count,
510 tw_dev->max_posted_request_count,
511 tw_dev->pending_request_count,
512 tw_dev->max_pending_request_count,
513 tw_dev->sgl_entries,
514 tw_dev->max_sgl_entries,
515 tw_dev->sector_count,
516 tw_dev->max_sector_count,
517 tw_dev->num_resets,
518 tw_dev->aen_count);
519 spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
520 return len;
521}
522
523
524static int tw_change_queue_depth(struct scsi_device *sdev, int queue_depth)
525{
526 if (queue_depth > TW_Q_LENGTH-2)
527 queue_depth = TW_Q_LENGTH-2;
528 scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG, queue_depth);
529 return queue_depth;
530}
531
532
533static struct device_attribute tw_host_stats_attr = {
534 .attr = {
535 .name = "stats",
536 .mode = S_IRUGO,
537 },
538 .show = tw_show_stats
539};
540
541
542static struct device_attribute *tw_host_attrs[] = {
543 &tw_host_stats_attr,
544 NULL,
545};
546
547
548static int tw_aen_read_queue(TW_Device_Extension *tw_dev, int request_id)
549{
550 TW_Command *command_packet;
551 TW_Param *param;
552 unsigned long command_que_value;
553 u32 status_reg_value;
554 unsigned long param_value = 0;
555
556 dprintk(KERN_NOTICE "3w-xxxx: tw_aen_read_queue()\n");
557
558 status_reg_value = inl(TW_STATUS_REG_ADDR(tw_dev));
559 if (tw_check_bits(status_reg_value)) {
560 dprintk(KERN_WARNING "3w-xxxx: tw_aen_read_queue(): Unexpected bits.\n");
561 tw_decode_bits(tw_dev, status_reg_value, 1);
562 return 1;
563 }
564 if (tw_dev->command_packet_virtual_address[request_id] == NULL) {
565 printk(KERN_WARNING "3w-xxxx: tw_aen_read_queue(): Bad command packet virtual address.\n");
566 return 1;
567 }
568 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
569 memset(command_packet, 0, sizeof(TW_Sector));
570 command_packet->opcode__sgloffset = TW_OPSGL_IN(2, TW_OP_GET_PARAM);
571 command_packet->size = 4;
572 command_packet->request_id = request_id;
573 command_packet->status = 0;
574 command_packet->flags = 0;
575 command_packet->byte6.parameter_count = 1;
576 command_que_value = tw_dev->command_packet_physical_address[request_id];
577 if (command_que_value == 0) {
578 printk(KERN_WARNING "3w-xxxx: tw_aen_read_queue(): Bad command packet physical address.\n");
579 return 1;
580 }
581
582 if (tw_dev->alignment_virtual_address[request_id] == NULL) {
583 printk(KERN_WARNING "3w-xxxx: tw_aen_read_queue(): Bad alignment virtual address.\n");
584 return 1;
585 }
586 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
587 memset(param, 0, sizeof(TW_Sector));
588 param->table_id = 0x401;
589 param->parameter_id = 2;
590 param->parameter_size_bytes = 2;
591 param_value = tw_dev->alignment_physical_address[request_id];
592 if (param_value == 0) {
593 printk(KERN_WARNING "3w-xxxx: tw_aen_read_queue(): Bad alignment physical address.\n");
594 return 1;
595 }
596 command_packet->byte8.param.sgl[0].address = param_value;
597 command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
598
599
600 if ((status_reg_value & TW_STATUS_COMMAND_QUEUE_FULL) == 0) {
601 dprintk(KERN_WARNING "3w-xxxx: tw_aen_read_queue(): Post succeeded.\n");
602 tw_dev->srb[request_id] = NULL;
603 tw_dev->state[request_id] = TW_S_POSTED;
604 outl(command_que_value, TW_COMMAND_QUEUE_REG_ADDR(tw_dev));
605 } else {
606 printk(KERN_WARNING "3w-xxxx: tw_aen_read_queue(): Post failed, will retry.\n");
607 return 1;
608 }
609
610 return 0;
611}
612
613
614static int tw_aen_complete(TW_Device_Extension *tw_dev, int request_id)
615{
616 TW_Param *param;
617 unsigned short aen;
618 int error = 0, table_max = 0;
619
620 dprintk(KERN_WARNING "3w-xxxx: tw_aen_complete()\n");
621 if (tw_dev->alignment_virtual_address[request_id] == NULL) {
622 printk(KERN_WARNING "3w-xxxx: tw_aen_complete(): Bad alignment virtual address.\n");
623 return 1;
624 }
625 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
626 aen = *(unsigned short *)(param->data);
627 dprintk(KERN_NOTICE "3w-xxxx: tw_aen_complete(): Queue'd code 0x%x\n", aen);
628
629
630 if (aen == 0x0ff) {
631 printk(KERN_WARNING "3w-xxxx: scsi%d: AEN: INFO: AEN queue overflow.\n", tw_dev->host->host_no);
632 } else {
633 table_max = ARRAY_SIZE(tw_aen_string);
634 if ((aen & 0x0ff) < table_max) {
635 if ((tw_aen_string[aen & 0xff][strlen(tw_aen_string[aen & 0xff])-1]) == '#') {
636 printk(KERN_WARNING "3w-xxxx: scsi%d: AEN: %s%d.\n", tw_dev->host->host_no, tw_aen_string[aen & 0xff], aen >> 8);
637 } else {
638 if (aen != 0x0)
639 printk(KERN_WARNING "3w-xxxx: scsi%d: AEN: %s.\n", tw_dev->host->host_no, tw_aen_string[aen & 0xff]);
640 }
641 } else {
642 printk(KERN_WARNING "3w-xxxx: scsi%d: Received AEN %d.\n", tw_dev->host->host_no, aen);
643 }
644 }
645 if (aen != TW_AEN_QUEUE_EMPTY) {
646 tw_dev->aen_count++;
647
648
649 tw_dev->aen_queue[tw_dev->aen_tail] = aen;
650 if (tw_dev->aen_tail == TW_Q_LENGTH - 1) {
651 tw_dev->aen_tail = TW_Q_START;
652 } else {
653 tw_dev->aen_tail = tw_dev->aen_tail + 1;
654 }
655 if (tw_dev->aen_head == tw_dev->aen_tail) {
656 if (tw_dev->aen_head == TW_Q_LENGTH - 1) {
657 tw_dev->aen_head = TW_Q_START;
658 } else {
659 tw_dev->aen_head = tw_dev->aen_head + 1;
660 }
661 }
662
663 error = tw_aen_read_queue(tw_dev, request_id);
664 if (error) {
665 printk(KERN_WARNING "3w-xxxx: scsi%d: Error completing AEN.\n", tw_dev->host->host_no);
666 tw_dev->state[request_id] = TW_S_COMPLETED;
667 tw_state_request_finish(tw_dev, request_id);
668 }
669 } else {
670 tw_dev->state[request_id] = TW_S_COMPLETED;
671 tw_state_request_finish(tw_dev, request_id);
672 }
673
674 return 0;
675}
676
677
678static int tw_aen_drain_queue(TW_Device_Extension *tw_dev)
679{
680 TW_Command *command_packet;
681 TW_Param *param;
682 int request_id = 0;
683 unsigned long command_que_value;
684 unsigned long param_value;
685 TW_Response_Queue response_queue;
686 unsigned short aen;
687 unsigned short aen_code;
688 int finished = 0;
689 int first_reset = 0;
690 int queue = 0;
691 int found = 0, table_max = 0;
692
693 dprintk(KERN_NOTICE "3w-xxxx: tw_aen_drain_queue()\n");
694
695 if (tw_poll_status(tw_dev, TW_STATUS_ATTENTION_INTERRUPT | TW_STATUS_MICROCONTROLLER_READY, 30)) {
696 dprintk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): No attention interrupt for card %d.\n", tw_device_extension_count);
697 return 1;
698 }
699 TW_CLEAR_ATTENTION_INTERRUPT(tw_dev);
700
701
702 tw_empty_response_que(tw_dev);
703
704
705 if (tw_dev->command_packet_virtual_address[request_id] == NULL) {
706 printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Bad command packet virtual address.\n");
707 return 1;
708 }
709 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
710 memset(command_packet, 0, sizeof(TW_Sector));
711 command_packet->opcode__sgloffset = TW_OPSGL_IN(2, TW_OP_GET_PARAM);
712 command_packet->size = 4;
713 command_packet->request_id = request_id;
714 command_packet->status = 0;
715 command_packet->flags = 0;
716 command_packet->byte6.parameter_count = 1;
717 command_que_value = tw_dev->command_packet_physical_address[request_id];
718 if (command_que_value == 0) {
719 printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Bad command packet physical address.\n");
720 return 1;
721 }
722
723
724 if (tw_dev->alignment_virtual_address[request_id] == NULL) {
725 printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Bad alignment virtual address.\n");
726 return 1;
727 }
728 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
729 memset(param, 0, sizeof(TW_Sector));
730 param->table_id = 0x401;
731 param->parameter_id = 2;
732 param->parameter_size_bytes = 2;
733 param_value = tw_dev->alignment_physical_address[request_id];
734 if (param_value == 0) {
735 printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Bad alignment physical address.\n");
736 return 1;
737 }
738 command_packet->byte8.param.sgl[0].address = param_value;
739 command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
740
741
742 do {
743
744 outl(command_que_value, TW_COMMAND_QUEUE_REG_ADDR(tw_dev));
745
746
747 if (tw_poll_status_gone(tw_dev, TW_STATUS_RESPONSE_QUEUE_EMPTY, 30) == 0) {
748 response_queue.value = inl(TW_RESPONSE_QUEUE_REG_ADDR(tw_dev));
749 request_id = TW_RESID_OUT(response_queue.response_id);
750
751 if (request_id != 0) {
752
753 printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Unexpected request id.\n");
754 return 1;
755 }
756
757 if (command_packet->status != 0) {
758 if (command_packet->flags != TW_AEN_TABLE_UNDEFINED) {
759
760 tw_decode_sense(tw_dev, request_id, 0);
761 return 1;
762 } else {
763
764 return 0;
765 }
766 }
767
768
769 aen = *(unsigned short *)(param->data);
770 aen_code = (aen & 0x0ff);
771 queue = 0;
772 switch (aen_code) {
773 case TW_AEN_QUEUE_EMPTY:
774 dprintk(KERN_WARNING "3w-xxxx: AEN: %s.\n", tw_aen_string[aen & 0xff]);
775 if (first_reset != 1) {
776 return 1;
777 } else {
778 finished = 1;
779 }
780 break;
781 case TW_AEN_SOFT_RESET:
782 if (first_reset == 0) {
783 first_reset = 1;
784 } else {
785 printk(KERN_WARNING "3w-xxxx: AEN: %s.\n", tw_aen_string[aen & 0xff]);
786 tw_dev->aen_count++;
787 queue = 1;
788 }
789 break;
790 default:
791 if (aen == 0x0ff) {
792 printk(KERN_WARNING "3w-xxxx: AEN: INFO: AEN queue overflow.\n");
793 } else {
794 table_max = ARRAY_SIZE(tw_aen_string);
795 if ((aen & 0x0ff) < table_max) {
796 if ((tw_aen_string[aen & 0xff][strlen(tw_aen_string[aen & 0xff])-1]) == '#') {
797 printk(KERN_WARNING "3w-xxxx: AEN: %s%d.\n", tw_aen_string[aen & 0xff], aen >> 8);
798 } else {
799 printk(KERN_WARNING "3w-xxxx: AEN: %s.\n", tw_aen_string[aen & 0xff]);
800 }
801 } else
802 printk(KERN_WARNING "3w-xxxx: Received AEN %d.\n", aen);
803 }
804 tw_dev->aen_count++;
805 queue = 1;
806 }
807
808
809 if (queue == 1) {
810 tw_dev->aen_queue[tw_dev->aen_tail] = aen;
811 if (tw_dev->aen_tail == TW_Q_LENGTH - 1) {
812 tw_dev->aen_tail = TW_Q_START;
813 } else {
814 tw_dev->aen_tail = tw_dev->aen_tail + 1;
815 }
816 if (tw_dev->aen_head == tw_dev->aen_tail) {
817 if (tw_dev->aen_head == TW_Q_LENGTH - 1) {
818 tw_dev->aen_head = TW_Q_START;
819 } else {
820 tw_dev->aen_head = tw_dev->aen_head + 1;
821 }
822 }
823 }
824 found = 1;
825 }
826 if (found == 0) {
827 printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Response never received.\n");
828 return 1;
829 }
830 } while (finished == 0);
831
832 return 0;
833}
834
835
836static int tw_allocate_memory(TW_Device_Extension *tw_dev, int size, int which)
837{
838 int i;
839 dma_addr_t dma_handle;
840 unsigned long *cpu_addr = NULL;
841
842 dprintk(KERN_NOTICE "3w-xxxx: tw_allocate_memory()\n");
843
844 cpu_addr = pci_alloc_consistent(tw_dev->tw_pci_dev, size*TW_Q_LENGTH, &dma_handle);
845 if (cpu_addr == NULL) {
846 printk(KERN_WARNING "3w-xxxx: pci_alloc_consistent() failed.\n");
847 return 1;
848 }
849
850 if ((unsigned long)cpu_addr % (tw_dev->tw_pci_dev->device == TW_DEVICE_ID ? TW_ALIGNMENT_6000 : TW_ALIGNMENT_7000)) {
851 printk(KERN_WARNING "3w-xxxx: Couldn't allocate correctly aligned memory.\n");
852 pci_free_consistent(tw_dev->tw_pci_dev, size*TW_Q_LENGTH, cpu_addr, dma_handle);
853 return 1;
854 }
855
856 memset(cpu_addr, 0, size*TW_Q_LENGTH);
857
858 for (i=0;i<TW_Q_LENGTH;i++) {
859 switch(which) {
860 case 0:
861 tw_dev->command_packet_physical_address[i] = dma_handle+(i*size);
862 tw_dev->command_packet_virtual_address[i] = (unsigned long *)((unsigned char *)cpu_addr + (i*size));
863 break;
864 case 1:
865 tw_dev->alignment_physical_address[i] = dma_handle+(i*size);
866 tw_dev->alignment_virtual_address[i] = (unsigned long *)((unsigned char *)cpu_addr + (i*size));
867 break;
868 default:
869 printk(KERN_WARNING "3w-xxxx: tw_allocate_memory(): case slip in tw_allocate_memory()\n");
870 return 1;
871 }
872 }
873
874 return 0;
875}
876
877
878static int tw_chrdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
879{
880 int request_id;
881 dma_addr_t dma_handle;
882 unsigned short tw_aen_code;
883 unsigned long flags;
884 unsigned int data_buffer_length = 0;
885 unsigned long data_buffer_length_adjusted = 0;
886 unsigned long *cpu_addr;
887 long timeout;
888 TW_New_Ioctl *tw_ioctl;
889 TW_Passthru *passthru;
890 TW_Device_Extension *tw_dev = tw_device_extension_list[iminor(inode)];
891 int retval = -EFAULT;
892 void __user *argp = (void __user *)arg;
893
894 dprintk(KERN_WARNING "3w-xxxx: tw_chrdev_ioctl()\n");
895
896
897 if (mutex_lock_interruptible(&tw_dev->ioctl_lock))
898 return -EINTR;
899
900
901 if (copy_from_user(&data_buffer_length, argp, sizeof(unsigned int)))
902 goto out;
903
904
905 if (data_buffer_length > TW_MAX_IOCTL_SECTORS * 512) {
906 retval = -EINVAL;
907 goto out;
908 }
909
910
911 data_buffer_length_adjusted = (data_buffer_length + 511) & ~511;
912
913
914 cpu_addr = dma_alloc_coherent(&tw_dev->tw_pci_dev->dev, data_buffer_length_adjusted+sizeof(TW_New_Ioctl) - 1, &dma_handle, GFP_KERNEL);
915 if (cpu_addr == NULL) {
916 retval = -ENOMEM;
917 goto out;
918 }
919
920 tw_ioctl = (TW_New_Ioctl *)cpu_addr;
921
922
923 if (copy_from_user(tw_ioctl, argp, data_buffer_length + sizeof(TW_New_Ioctl) - 1))
924 goto out2;
925
926 passthru = (TW_Passthru *)&tw_ioctl->firmware_command;
927
928
929 switch (cmd) {
930 case TW_OP_NOP:
931 dprintk(KERN_WARNING "3w-xxxx: tw_chrdev_ioctl(): caught TW_OP_NOP.\n");
932 break;
933 case TW_OP_AEN_LISTEN:
934 dprintk(KERN_WARNING "3w-xxxx: tw_chrdev_ioctl(): caught TW_AEN_LISTEN.\n");
935 memset(tw_ioctl->data_buffer, 0, data_buffer_length);
936
937 spin_lock_irqsave(tw_dev->host->host_lock, flags);
938 if (tw_dev->aen_head == tw_dev->aen_tail) {
939 tw_aen_code = TW_AEN_QUEUE_EMPTY;
940 } else {
941 tw_aen_code = tw_dev->aen_queue[tw_dev->aen_head];
942 if (tw_dev->aen_head == TW_Q_LENGTH - 1) {
943 tw_dev->aen_head = TW_Q_START;
944 } else {
945 tw_dev->aen_head = tw_dev->aen_head + 1;
946 }
947 }
948 spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
949 memcpy(tw_ioctl->data_buffer, &tw_aen_code, sizeof(tw_aen_code));
950 break;
951 case TW_CMD_PACKET_WITH_DATA:
952 dprintk(KERN_WARNING "3w-xxxx: tw_chrdev_ioctl(): caught TW_CMD_PACKET_WITH_DATA.\n");
953 spin_lock_irqsave(tw_dev->host->host_lock, flags);
954
955 tw_state_request_start(tw_dev, &request_id);
956
957
958 tw_dev->srb[request_id] = NULL;
959
960
961 tw_dev->chrdev_request_id = request_id;
962
963 tw_ioctl->firmware_command.request_id = request_id;
964
965
966 switch (TW_SGL_OUT(tw_ioctl->firmware_command.opcode__sgloffset)) {
967 case 2:
968 tw_ioctl->firmware_command.byte8.param.sgl[0].address = dma_handle + sizeof(TW_New_Ioctl) - 1;
969 tw_ioctl->firmware_command.byte8.param.sgl[0].length = data_buffer_length_adjusted;
970 break;
971 case 3:
972 tw_ioctl->firmware_command.byte8.io.sgl[0].address = dma_handle + sizeof(TW_New_Ioctl) - 1;
973 tw_ioctl->firmware_command.byte8.io.sgl[0].length = data_buffer_length_adjusted;
974 break;
975 case 5:
976 passthru->sg_list[0].address = dma_handle + sizeof(TW_New_Ioctl) - 1;
977 passthru->sg_list[0].length = data_buffer_length_adjusted;
978 break;
979 }
980
981 memcpy(tw_dev->command_packet_virtual_address[request_id], &(tw_ioctl->firmware_command), sizeof(TW_Command));
982
983
984 tw_post_command_packet(tw_dev, request_id);
985 spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
986
987 timeout = TW_IOCTL_CHRDEV_TIMEOUT*HZ;
988
989
990 timeout = wait_event_timeout(tw_dev->ioctl_wqueue, tw_dev->chrdev_request_id == TW_IOCTL_CHRDEV_FREE, timeout);
991
992
993 if (tw_dev->chrdev_request_id != TW_IOCTL_CHRDEV_FREE) {
994
995 printk(KERN_WARNING "3w-xxxx: scsi%d: Character ioctl (0x%x) timed out, resetting card.\n", tw_dev->host->host_no, cmd);
996 retval = -EIO;
997 if (tw_reset_device_extension(tw_dev)) {
998 printk(KERN_WARNING "3w-xxxx: tw_chrdev_ioctl(): Reset failed for card %d.\n", tw_dev->host->host_no);
999 }
1000 goto out2;
1001 }
1002
1003
1004 memcpy(&(tw_ioctl->firmware_command), tw_dev->command_packet_virtual_address[request_id], sizeof(TW_Command));
1005
1006
1007 spin_lock_irqsave(tw_dev->host->host_lock, flags);
1008 tw_dev->posted_request_count--;
1009 tw_dev->state[request_id] = TW_S_COMPLETED;
1010 tw_state_request_finish(tw_dev, request_id);
1011 spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
1012 break;
1013 default:
1014 retval = -ENOTTY;
1015 goto out2;
1016 }
1017
1018
1019 if (copy_to_user(argp, tw_ioctl, sizeof(TW_New_Ioctl) + data_buffer_length - 1))
1020 goto out2;
1021 retval = 0;
1022out2:
1023
1024 dma_free_coherent(&tw_dev->tw_pci_dev->dev, data_buffer_length_adjusted+sizeof(TW_New_Ioctl) - 1, cpu_addr, dma_handle);
1025out:
1026 mutex_unlock(&tw_dev->ioctl_lock);
1027 return retval;
1028}
1029
1030
1031
1032static int tw_chrdev_open(struct inode *inode, struct file *file)
1033{
1034 unsigned int minor_number;
1035
1036 cycle_kernel_lock();
1037 dprintk(KERN_WARNING "3w-xxxx: tw_ioctl_open()\n");
1038
1039 minor_number = iminor(inode);
1040 if (minor_number >= tw_device_extension_count)
1041 return -ENODEV;
1042
1043 return 0;
1044}
1045
1046
1047static const struct file_operations tw_fops = {
1048 .owner = THIS_MODULE,
1049 .ioctl = tw_chrdev_ioctl,
1050 .open = tw_chrdev_open,
1051 .release = NULL
1052};
1053
1054
1055static void tw_free_device_extension(TW_Device_Extension *tw_dev)
1056{
1057 dprintk(KERN_NOTICE "3w-xxxx: tw_free_device_extension()\n");
1058
1059
1060 if (tw_dev->command_packet_virtual_address[0])
1061 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]);
1062
1063 if (tw_dev->alignment_virtual_address[0])
1064 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]);
1065}
1066
1067
1068static int tw_initconnection(TW_Device_Extension *tw_dev, int message_credits)
1069{
1070 unsigned long command_que_value;
1071 TW_Command *command_packet;
1072 TW_Response_Queue response_queue;
1073 int request_id = 0;
1074
1075 dprintk(KERN_NOTICE "3w-xxxx: tw_initconnection()\n");
1076
1077
1078 if (tw_dev->command_packet_virtual_address[request_id] == NULL) {
1079 printk(KERN_WARNING "3w-xxxx: tw_initconnection(): Bad command packet virtual address.\n");
1080 return 1;
1081 }
1082
1083 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
1084 memset(command_packet, 0, sizeof(TW_Sector));
1085 command_packet->opcode__sgloffset = TW_OPSGL_IN(0, TW_OP_INIT_CONNECTION);
1086 command_packet->size = TW_INIT_COMMAND_PACKET_SIZE;
1087 command_packet->request_id = request_id;
1088 command_packet->status = 0x0;
1089 command_packet->flags = 0x0;
1090 command_packet->byte6.message_credits = message_credits;
1091 command_packet->byte8.init_connection.response_queue_pointer = 0x0;
1092 command_que_value = tw_dev->command_packet_physical_address[request_id];
1093
1094 if (command_que_value == 0) {
1095 printk(KERN_WARNING "3w-xxxx: tw_initconnection(): Bad command packet physical address.\n");
1096 return 1;
1097 }
1098
1099
1100 outl(command_que_value, TW_COMMAND_QUEUE_REG_ADDR(tw_dev));
1101
1102
1103 if (tw_poll_status_gone(tw_dev, TW_STATUS_RESPONSE_QUEUE_EMPTY, 30) == 0) {
1104 response_queue.value = inl(TW_RESPONSE_QUEUE_REG_ADDR(tw_dev));
1105 request_id = TW_RESID_OUT(response_queue.response_id);
1106
1107 if (request_id != 0) {
1108
1109 printk(KERN_WARNING "3w-xxxx: tw_initconnection(): Unexpected request id.\n");
1110 return 1;
1111 }
1112 if (command_packet->status != 0) {
1113
1114 tw_decode_sense(tw_dev, request_id, 0);
1115 return 1;
1116 }
1117 }
1118 return 0;
1119}
1120
1121
1122static int tw_setfeature(TW_Device_Extension *tw_dev, int parm, int param_size,
1123 unsigned char *val)
1124{
1125 TW_Param *param;
1126 TW_Command *command_packet;
1127 TW_Response_Queue response_queue;
1128 int request_id = 0;
1129 unsigned long command_que_value;
1130 unsigned long param_value;
1131
1132
1133 if (tw_dev->command_packet_virtual_address[request_id] == NULL) {
1134 printk(KERN_WARNING "3w-xxxx: tw_setfeature(): Bad command packet virtual address.\n");
1135 return 1;
1136 }
1137 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
1138 memset(command_packet, 0, sizeof(TW_Sector));
1139 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
1140
1141 command_packet->opcode__sgloffset = TW_OPSGL_IN(2, TW_OP_SET_PARAM);
1142 param->table_id = 0x404;
1143 param->parameter_id = parm;
1144 param->parameter_size_bytes = param_size;
1145 memcpy(param->data, val, param_size);
1146
1147 param_value = tw_dev->alignment_physical_address[request_id];
1148 if (param_value == 0) {
1149 printk(KERN_WARNING "3w-xxxx: tw_setfeature(): Bad alignment physical address.\n");
1150 tw_dev->state[request_id] = TW_S_COMPLETED;
1151 tw_state_request_finish(tw_dev, request_id);
1152 tw_dev->srb[request_id]->result = (DID_OK << 16);
1153 tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
1154 }
1155 command_packet->byte8.param.sgl[0].address = param_value;
1156 command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
1157
1158 command_packet->size = 4;
1159 command_packet->request_id = request_id;
1160 command_packet->byte6.parameter_count = 1;
1161
1162 command_que_value = tw_dev->command_packet_physical_address[request_id];
1163 if (command_que_value == 0) {
1164 printk(KERN_WARNING "3w-xxxx: tw_setfeature(): Bad command packet physical address.\n");
1165 return 1;
1166 }
1167
1168
1169 outl(command_que_value, TW_COMMAND_QUEUE_REG_ADDR(tw_dev));
1170
1171
1172 if (tw_poll_status_gone(tw_dev, TW_STATUS_RESPONSE_QUEUE_EMPTY, 30) == 0) {
1173 response_queue.value = inl(TW_RESPONSE_QUEUE_REG_ADDR(tw_dev));
1174 request_id = TW_RESID_OUT(response_queue.response_id);
1175
1176 if (request_id != 0) {
1177
1178 printk(KERN_WARNING "3w-xxxx: tw_setfeature(): Unexpected request id.\n");
1179 return 1;
1180 }
1181 if (command_packet->status != 0) {
1182
1183 tw_decode_sense(tw_dev, request_id, 0);
1184 return 1;
1185 }
1186 }
1187
1188 return 0;
1189}
1190
1191
1192static int tw_reset_sequence(TW_Device_Extension *tw_dev)
1193{
1194 int error = 0;
1195 int tries = 0;
1196 unsigned char c = 1;
1197
1198
1199 while (tries < TW_MAX_RESET_TRIES) {
1200 TW_SOFT_RESET(tw_dev);
1201
1202 error = tw_aen_drain_queue(tw_dev);
1203 if (error) {
1204 printk(KERN_WARNING "3w-xxxx: scsi%d: AEN drain failed, retrying.\n", tw_dev->host->host_no);
1205 tries++;
1206 continue;
1207 }
1208
1209
1210 if (tw_check_errors(tw_dev)) {
1211 printk(KERN_WARNING "3w-xxxx: scsi%d: Controller errors found, retrying.\n", tw_dev->host->host_no);
1212 tries++;
1213 continue;
1214 }
1215
1216
1217 break;
1218 }
1219
1220 if (tries >= TW_MAX_RESET_TRIES) {
1221 printk(KERN_WARNING "3w-xxxx: scsi%d: Controller errors, card not responding, check all cabling.\n", tw_dev->host->host_no);
1222 return 1;
1223 }
1224
1225 error = tw_initconnection(tw_dev, TW_INIT_MESSAGE_CREDITS);
1226 if (error) {
1227 printk(KERN_WARNING "3w-xxxx: scsi%d: Connection initialization failed.\n", tw_dev->host->host_no);
1228 return 1;
1229 }
1230
1231 error = tw_setfeature(tw_dev, 2, 1, &c);
1232 if (error) {
1233 printk(KERN_WARNING "3w-xxxx: Unable to set features for card, probable old firmware or card.\n");
1234 }
1235
1236 return 0;
1237}
1238
1239
1240static int tw_initialize_device_extension(TW_Device_Extension *tw_dev)
1241{
1242 int i, error=0;
1243
1244 dprintk(KERN_NOTICE "3w-xxxx: tw_initialize_device_extension()\n");
1245
1246
1247 error = tw_allocate_memory(tw_dev, sizeof(TW_Command), 0);
1248 if (error) {
1249 printk(KERN_WARNING "3w-xxxx: Command packet memory allocation failed.\n");
1250 return 1;
1251 }
1252
1253
1254 error = tw_allocate_memory(tw_dev, sizeof(TW_Sector), 1);
1255 if (error) {
1256 printk(KERN_WARNING "3w-xxxx: Generic memory allocation failed.\n");
1257 return 1;
1258 }
1259
1260 for (i=0;i<TW_Q_LENGTH;i++) {
1261 tw_dev->free_queue[i] = i;
1262 tw_dev->state[i] = TW_S_INITIAL;
1263 }
1264
1265 tw_dev->pending_head = TW_Q_START;
1266 tw_dev->pending_tail = TW_Q_START;
1267 tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE;
1268
1269 mutex_init(&tw_dev->ioctl_lock);
1270 init_waitqueue_head(&tw_dev->ioctl_wqueue);
1271
1272 return 0;
1273}
1274
1275static int tw_map_scsi_sg_data(struct pci_dev *pdev, struct scsi_cmnd *cmd)
1276{
1277 int use_sg;
1278
1279 dprintk(KERN_WARNING "3w-xxxx: tw_map_scsi_sg_data()\n");
1280
1281 use_sg = scsi_dma_map(cmd);
1282 if (use_sg < 0) {
1283 printk(KERN_WARNING "3w-xxxx: tw_map_scsi_sg_data(): pci_map_sg() failed.\n");
1284 return 0;
1285 }
1286
1287 cmd->SCp.phase = TW_PHASE_SGLIST;
1288 cmd->SCp.have_data_in = use_sg;
1289
1290 return use_sg;
1291}
1292
1293static void tw_unmap_scsi_data(struct pci_dev *pdev, struct scsi_cmnd *cmd)
1294{
1295 dprintk(KERN_WARNING "3w-xxxx: tw_unmap_scsi_data()\n");
1296
1297 if (cmd->SCp.phase == TW_PHASE_SGLIST)
1298 scsi_dma_unmap(cmd);
1299}
1300
1301
1302static int tw_reset_device_extension(TW_Device_Extension *tw_dev)
1303{
1304 int i = 0;
1305 struct scsi_cmnd *srb;
1306 unsigned long flags = 0;
1307
1308 dprintk(KERN_NOTICE "3w-xxxx: tw_reset_device_extension()\n");
1309
1310 set_bit(TW_IN_RESET, &tw_dev->flags);
1311 TW_DISABLE_INTERRUPTS(tw_dev);
1312 TW_MASK_COMMAND_INTERRUPT(tw_dev);
1313 spin_lock_irqsave(tw_dev->host->host_lock, flags);
1314
1315
1316 for (i=0;i<TW_Q_LENGTH;i++) {
1317 if ((tw_dev->state[i] != TW_S_FINISHED) &&
1318 (tw_dev->state[i] != TW_S_INITIAL) &&
1319 (tw_dev->state[i] != TW_S_COMPLETED)) {
1320 srb = tw_dev->srb[i];
1321 if (srb != NULL) {
1322 srb->result = (DID_RESET << 16);
1323 tw_dev->srb[i]->scsi_done(tw_dev->srb[i]);
1324 tw_unmap_scsi_data(tw_dev->tw_pci_dev, tw_dev->srb[i]);
1325 }
1326 }
1327 }
1328
1329
1330 for (i=0;i<TW_Q_LENGTH;i++) {
1331 tw_dev->free_queue[i] = i;
1332 tw_dev->state[i] = TW_S_INITIAL;
1333 }
1334 tw_dev->free_head = TW_Q_START;
1335 tw_dev->free_tail = TW_Q_START;
1336 tw_dev->posted_request_count = 0;
1337 tw_dev->pending_request_count = 0;
1338 tw_dev->pending_head = TW_Q_START;
1339 tw_dev->pending_tail = TW_Q_START;
1340 tw_dev->reset_print = 0;
1341
1342 spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
1343
1344 if (tw_reset_sequence(tw_dev)) {
1345 printk(KERN_WARNING "3w-xxxx: scsi%d: Reset sequence failed.\n", tw_dev->host->host_no);
1346 return 1;
1347 }
1348
1349 TW_ENABLE_AND_CLEAR_INTERRUPTS(tw_dev);
1350 clear_bit(TW_IN_RESET, &tw_dev->flags);
1351 tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE;
1352
1353 return 0;
1354}
1355
1356
1357static int tw_scsi_biosparam(struct scsi_device *sdev, struct block_device *bdev,
1358 sector_t capacity, int geom[])
1359{
1360 int heads, sectors, cylinders;
1361 TW_Device_Extension *tw_dev;
1362
1363 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_biosparam()\n");
1364 tw_dev = (TW_Device_Extension *)sdev->host->hostdata;
1365
1366 heads = 64;
1367 sectors = 32;
1368 cylinders = sector_div(capacity, heads * sectors);
1369
1370 if (capacity >= 0x200000) {
1371 heads = 255;
1372 sectors = 63;
1373 cylinders = sector_div(capacity, heads * sectors);
1374 }
1375
1376 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_biosparam(): heads = %d, sectors = %d, cylinders = %d\n", heads, sectors, cylinders);
1377 geom[0] = heads;
1378 geom[1] = sectors;
1379 geom[2] = cylinders;
1380
1381 return 0;
1382}
1383
1384
1385static int tw_scsi_eh_reset(struct scsi_cmnd *SCpnt)
1386{
1387 TW_Device_Extension *tw_dev=NULL;
1388 int retval = FAILED;
1389
1390 tw_dev = (TW_Device_Extension *)SCpnt->device->host->hostdata;
1391
1392 tw_dev->num_resets++;
1393
1394 sdev_printk(KERN_WARNING, SCpnt->device,
1395 "WARNING: Command (0x%x) timed out, resetting card.\n",
1396 SCpnt->cmnd[0]);
1397
1398
1399 mutex_lock(&tw_dev->ioctl_lock);
1400
1401
1402 if (tw_reset_device_extension(tw_dev)) {
1403 printk(KERN_WARNING "3w-xxxx: scsi%d: Reset failed.\n", tw_dev->host->host_no);
1404 goto out;
1405 }
1406
1407 retval = SUCCESS;
1408out:
1409 mutex_unlock(&tw_dev->ioctl_lock);
1410 return retval;
1411}
1412
1413
1414static int tw_scsiop_inquiry(TW_Device_Extension *tw_dev, int request_id)
1415{
1416 TW_Param *param;
1417 TW_Command *command_packet;
1418 unsigned long command_que_value;
1419 unsigned long param_value;
1420
1421 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_inquiry()\n");
1422
1423
1424 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
1425 if (command_packet == NULL) {
1426 printk(KERN_WARNING "3w-xxxx: tw_scsiop_inquiry(): Bad command packet virtual address.\n");
1427 return 1;
1428 }
1429 memset(command_packet, 0, sizeof(TW_Sector));
1430 command_packet->opcode__sgloffset = TW_OPSGL_IN(2, TW_OP_GET_PARAM);
1431 command_packet->size = 4;
1432 command_packet->request_id = request_id;
1433 command_packet->status = 0;
1434 command_packet->flags = 0;
1435 command_packet->byte6.parameter_count = 1;
1436
1437
1438 if (tw_dev->alignment_virtual_address[request_id] == NULL) {
1439 printk(KERN_WARNING "3w-xxxx: tw_scsiop_inquiry(): Bad alignment virtual address.\n");
1440 return 1;
1441 }
1442 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
1443 memset(param, 0, sizeof(TW_Sector));
1444 param->table_id = 3;
1445 param->parameter_id = 3;
1446 param->parameter_size_bytes = TW_MAX_UNITS;
1447 param_value = tw_dev->alignment_physical_address[request_id];
1448 if (param_value == 0) {
1449 printk(KERN_WARNING "3w-xxxx: tw_scsiop_inquiry(): Bad alignment physical address.\n");
1450 return 1;
1451 }
1452
1453 command_packet->byte8.param.sgl[0].address = param_value;
1454 command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
1455 command_que_value = tw_dev->command_packet_physical_address[request_id];
1456 if (command_que_value == 0) {
1457 printk(KERN_WARNING "3w-xxxx: tw_scsiop_inquiry(): Bad command packet physical address.\n");
1458 return 1;
1459 }
1460
1461
1462 tw_post_command_packet(tw_dev, request_id);
1463
1464 return 0;
1465}
1466
1467static void tw_transfer_internal(TW_Device_Extension *tw_dev, int request_id,
1468 void *data, unsigned int len)
1469{
1470 scsi_sg_copy_from_buffer(tw_dev->srb[request_id], data, len);
1471}
1472
1473
1474static int tw_scsiop_inquiry_complete(TW_Device_Extension *tw_dev, int request_id)
1475{
1476 unsigned char *is_unit_present;
1477 unsigned char request_buffer[36];
1478 TW_Param *param;
1479
1480 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_inquiry_complete()\n");
1481
1482 memset(request_buffer, 0, sizeof(request_buffer));
1483 request_buffer[0] = TYPE_DISK;
1484 request_buffer[1] = 0;
1485 request_buffer[2] = 0;
1486 request_buffer[4] = 31;
1487 memcpy(&request_buffer[8], "3ware ", 8);
1488 sprintf(&request_buffer[16], "Logical Disk %-2d ", tw_dev->srb[request_id]->device->id);
1489 memcpy(&request_buffer[32], TW_DRIVER_VERSION, 3);
1490 tw_transfer_internal(tw_dev, request_id, request_buffer,
1491 sizeof(request_buffer));
1492
1493 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
1494 if (param == NULL) {
1495 printk(KERN_WARNING "3w-xxxx: tw_scsiop_inquiry_complete(): Bad alignment virtual address.\n");
1496 return 1;
1497 }
1498 is_unit_present = &(param->data[0]);
1499
1500 if (is_unit_present[tw_dev->srb[request_id]->device->id] & TW_UNIT_ONLINE) {
1501 tw_dev->is_unit_present[tw_dev->srb[request_id]->device->id] = 1;
1502 } else {
1503 tw_dev->is_unit_present[tw_dev->srb[request_id]->device->id] = 0;
1504 tw_dev->srb[request_id]->result = (DID_BAD_TARGET << 16);
1505 return TW_ISR_DONT_RESULT;
1506 }
1507
1508 return 0;
1509}
1510
1511
1512static int tw_scsiop_mode_sense(TW_Device_Extension *tw_dev, int request_id)
1513{
1514 TW_Param *param;
1515 TW_Command *command_packet;
1516 unsigned long command_que_value;
1517 unsigned long param_value;
1518
1519 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_mode_sense()\n");
1520
1521
1522 if (tw_dev->srb[request_id]->cmnd[2] != 0x8) {
1523 tw_dev->state[request_id] = TW_S_COMPLETED;
1524 tw_state_request_finish(tw_dev, request_id);
1525 tw_dev->srb[request_id]->result = (DID_OK << 16);
1526 tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
1527 return 0;
1528 }
1529
1530
1531 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
1532 if (command_packet == NULL) {
1533 printk(KERN_WARNING "3w-xxxx: tw_scsiop_mode_sense(): Bad command packet virtual address.\n");
1534 return 1;
1535 }
1536
1537
1538 memset(command_packet, 0, sizeof(TW_Sector));
1539 command_packet->opcode__sgloffset = TW_OPSGL_IN(2, TW_OP_GET_PARAM);
1540 command_packet->size = 4;
1541 command_packet->request_id = request_id;
1542 command_packet->status = 0;
1543 command_packet->flags = 0;
1544 command_packet->byte6.parameter_count = 1;
1545
1546
1547 if (tw_dev->alignment_virtual_address[request_id] == NULL) {
1548 printk(KERN_WARNING "3w-xxxx: tw_scsiop_mode_sense(): Bad alignment virtual address.\n");
1549 return 1;
1550 }
1551
1552 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
1553 memset(param, 0, sizeof(TW_Sector));
1554 param->table_id = TW_UNIT_INFORMATION_TABLE_BASE + tw_dev->srb[request_id]->device->id;
1555 param->parameter_id = 7;
1556 param->parameter_size_bytes = 1;
1557 param_value = tw_dev->alignment_physical_address[request_id];
1558 if (param_value == 0) {
1559 printk(KERN_WARNING "3w-xxxx: tw_scsiop_mode_sense(): Bad alignment physical address.\n");
1560 return 1;
1561 }
1562
1563 command_packet->byte8.param.sgl[0].address = param_value;
1564 command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
1565 command_que_value = tw_dev->command_packet_physical_address[request_id];
1566 if (command_que_value == 0) {
1567 printk(KERN_WARNING "3w-xxxx: tw_scsiop_mode_sense(): Bad command packet physical address.\n");
1568 return 1;
1569 }
1570
1571
1572 tw_post_command_packet(tw_dev, request_id);
1573
1574 return 0;
1575}
1576
1577
1578static int tw_scsiop_mode_sense_complete(TW_Device_Extension *tw_dev, int request_id)
1579{
1580 TW_Param *param;
1581 unsigned char *flags;
1582 unsigned char request_buffer[8];
1583
1584 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_mode_sense_complete()\n");
1585
1586 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
1587 if (param == NULL) {
1588 printk(KERN_WARNING "3w-xxxx: tw_scsiop_mode_sense_complete(): Bad alignment virtual address.\n");
1589 return 1;
1590 }
1591 flags = (char *)&(param->data[0]);
1592 memset(request_buffer, 0, sizeof(request_buffer));
1593
1594 request_buffer[0] = 0xf;
1595 request_buffer[1] = 0;
1596 request_buffer[2] = 0x10;
1597 request_buffer[3] = 0;
1598 request_buffer[4] = 0x8;
1599 request_buffer[5] = 0xa;
1600 if (*flags & 0x1)
1601 request_buffer[6] = 0x5;
1602 else
1603 request_buffer[6] = 0x1;
1604 tw_transfer_internal(tw_dev, request_id, request_buffer,
1605 sizeof(request_buffer));
1606
1607 return 0;
1608}
1609
1610
1611static int tw_scsiop_read_capacity(TW_Device_Extension *tw_dev, int request_id)
1612{
1613 TW_Param *param;
1614 TW_Command *command_packet;
1615 unsigned long command_que_value;
1616 unsigned long param_value;
1617
1618 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity()\n");
1619
1620
1621 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
1622
1623 if (command_packet == NULL) {
1624 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity(): Bad command packet virtual address.\n");
1625 return 1;
1626 }
1627 memset(command_packet, 0, sizeof(TW_Sector));
1628 command_packet->opcode__sgloffset = TW_OPSGL_IN(2, TW_OP_GET_PARAM);
1629 command_packet->size = 4;
1630 command_packet->request_id = request_id;
1631 command_packet->unit__hostid = TW_UNITHOST_IN(0, tw_dev->srb[request_id]->device->id);
1632 command_packet->status = 0;
1633 command_packet->flags = 0;
1634 command_packet->byte6.block_count = 1;
1635
1636
1637 if (tw_dev->alignment_virtual_address[request_id] == NULL) {
1638 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity(): Bad alignment virtual address.\n");
1639 return 1;
1640 }
1641 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
1642 memset(param, 0, sizeof(TW_Sector));
1643 param->table_id = TW_UNIT_INFORMATION_TABLE_BASE +
1644 tw_dev->srb[request_id]->device->id;
1645 param->parameter_id = 4;
1646 param->parameter_size_bytes = 4;
1647 param_value = tw_dev->alignment_physical_address[request_id];
1648 if (param_value == 0) {
1649 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity(): Bad alignment physical address.\n");
1650 return 1;
1651 }
1652
1653 command_packet->byte8.param.sgl[0].address = param_value;
1654 command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
1655 command_que_value = tw_dev->command_packet_physical_address[request_id];
1656 if (command_que_value == 0) {
1657 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity(): Bad command packet physical address.\n");
1658 return 1;
1659 }
1660
1661
1662 tw_post_command_packet(tw_dev, request_id);
1663
1664 return 0;
1665}
1666
1667
1668static int tw_scsiop_read_capacity_complete(TW_Device_Extension *tw_dev, int request_id)
1669{
1670 unsigned char *param_data;
1671 u32 capacity;
1672 char buff[8];
1673 TW_Param *param;
1674
1675 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity_complete()\n");
1676
1677 memset(buff, 0, sizeof(buff));
1678 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
1679 if (param == NULL) {
1680 printk(KERN_WARNING "3w-xxxx: tw_scsiop_read_capacity_complete(): Bad alignment virtual address.\n");
1681 return 1;
1682 }
1683 param_data = &(param->data[0]);
1684
1685 capacity = (param_data[3] << 24) | (param_data[2] << 16) |
1686 (param_data[1] << 8) | param_data[0];
1687
1688
1689 capacity -= 1;
1690
1691 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity_complete(): Capacity = 0x%x.\n", capacity);
1692
1693
1694 buff[0] = (capacity >> 24);
1695 buff[1] = (capacity >> 16) & 0xff;
1696 buff[2] = (capacity >> 8) & 0xff;
1697 buff[3] = capacity & 0xff;
1698
1699
1700 buff[4] = (TW_BLOCK_SIZE >> 24);
1701 buff[5] = (TW_BLOCK_SIZE >> 16) & 0xff;
1702 buff[6] = (TW_BLOCK_SIZE >> 8) & 0xff;
1703 buff[7] = TW_BLOCK_SIZE & 0xff;
1704
1705 tw_transfer_internal(tw_dev, request_id, buff, sizeof(buff));
1706
1707 return 0;
1708}
1709
1710
1711static int tw_scsiop_read_write(TW_Device_Extension *tw_dev, int request_id)
1712{
1713 TW_Command *command_packet;
1714 unsigned long command_que_value;
1715 u32 lba = 0x0, num_sectors = 0x0;
1716 int i, use_sg;
1717 struct scsi_cmnd *srb;
1718 struct scatterlist *sglist, *sg;
1719
1720 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_write()\n");
1721
1722 srb = tw_dev->srb[request_id];
1723
1724 sglist = scsi_sglist(srb);
1725 if (!sglist) {
1726 printk(KERN_WARNING "3w-xxxx: tw_scsiop_read_write(): Request buffer NULL.\n");
1727 return 1;
1728 }
1729
1730
1731 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
1732 if (command_packet == NULL) {
1733 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_write(): Bad command packet virtual address.\n");
1734 return 1;
1735 }
1736
1737 if (srb->cmnd[0] == READ_6 || srb->cmnd[0] == READ_10) {
1738 command_packet->opcode__sgloffset = TW_OPSGL_IN(3, TW_OP_READ);
1739 } else {
1740 command_packet->opcode__sgloffset = TW_OPSGL_IN(3, TW_OP_WRITE);
1741 }
1742
1743 command_packet->size = 3;
1744 command_packet->request_id = request_id;
1745 command_packet->unit__hostid = TW_UNITHOST_IN(0, srb->device->id);
1746 command_packet->status = 0;
1747 command_packet->flags = 0;
1748
1749 if (srb->cmnd[0] == WRITE_10) {
1750 if ((srb->cmnd[1] & 0x8) || (srb->cmnd[1] & 0x10))
1751 command_packet->flags = 1;
1752 }
1753
1754 if (srb->cmnd[0] == READ_6 || srb->cmnd[0] == WRITE_6) {
1755 lba = ((u32)srb->cmnd[1] << 16) | ((u32)srb->cmnd[2] << 8) | (u32)srb->cmnd[3];
1756 num_sectors = (u32)srb->cmnd[4];
1757 } else {
1758 lba = ((u32)srb->cmnd[2] << 24) | ((u32)srb->cmnd[3] << 16) | ((u32)srb->cmnd[4] << 8) | (u32)srb->cmnd[5];
1759 num_sectors = (u32)srb->cmnd[8] | ((u32)srb->cmnd[7] << 8);
1760 }
1761
1762
1763 tw_dev->sector_count = num_sectors;
1764 if (tw_dev->sector_count > tw_dev->max_sector_count)
1765 tw_dev->max_sector_count = tw_dev->sector_count;
1766
1767 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_write(): lba = 0x%x num_sectors = 0x%x\n", lba, num_sectors);
1768 command_packet->byte8.io.lba = lba;
1769 command_packet->byte6.block_count = num_sectors;
1770
1771 use_sg = tw_map_scsi_sg_data(tw_dev->tw_pci_dev, tw_dev->srb[request_id]);
1772 if (!use_sg)
1773 return 1;
1774
1775 scsi_for_each_sg(tw_dev->srb[request_id], sg, use_sg, i) {
1776 command_packet->byte8.io.sgl[i].address = sg_dma_address(sg);
1777 command_packet->byte8.io.sgl[i].length = sg_dma_len(sg);
1778 command_packet->size+=2;
1779 }
1780
1781
1782 tw_dev->sgl_entries = scsi_sg_count(tw_dev->srb[request_id]);
1783 if (tw_dev->sgl_entries > tw_dev->max_sgl_entries)
1784 tw_dev->max_sgl_entries = tw_dev->sgl_entries;
1785
1786 command_que_value = tw_dev->command_packet_physical_address[request_id];
1787 if (command_que_value == 0) {
1788 dprintk(KERN_WARNING "3w-xxxx: tw_scsiop_read_write(): Bad command packet physical address.\n");
1789 return 1;
1790 }
1791
1792
1793 tw_post_command_packet(tw_dev, request_id);
1794
1795 return 0;
1796}
1797
1798
1799static int tw_scsiop_request_sense(TW_Device_Extension *tw_dev, int request_id)
1800{
1801 char request_buffer[18];
1802
1803 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_request_sense()\n");
1804
1805 memset(request_buffer, 0, sizeof(request_buffer));
1806 request_buffer[0] = 0x70;
1807 request_buffer[7] = 10;
1808
1809 tw_transfer_internal(tw_dev, request_id, request_buffer,
1810 sizeof(request_buffer));
1811
1812 tw_dev->state[request_id] = TW_S_COMPLETED;
1813 tw_state_request_finish(tw_dev, request_id);
1814
1815
1816 tw_dev->srb[request_id]->result = (DID_ERROR << 16);
1817 tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
1818
1819 return 0;
1820}
1821
1822
1823static int tw_scsiop_synchronize_cache(TW_Device_Extension *tw_dev, int request_id)
1824{
1825 TW_Command *command_packet;
1826 unsigned long command_que_value;
1827
1828 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_synchronize_cache()\n");
1829
1830
1831 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
1832 if (command_packet == NULL) {
1833 printk(KERN_WARNING "3w-xxxx: tw_scsiop_synchronize_cache(): Bad command packet virtual address.\n");
1834 return 1;
1835 }
1836
1837
1838 memset(command_packet, 0, sizeof(TW_Sector));
1839 command_packet->opcode__sgloffset = TW_OPSGL_IN(0, TW_OP_FLUSH_CACHE);
1840 command_packet->size = 2;
1841 command_packet->request_id = request_id;
1842 command_packet->unit__hostid = TW_UNITHOST_IN(0, tw_dev->srb[request_id]->device->id);
1843 command_packet->status = 0;
1844 command_packet->flags = 0;
1845 command_packet->byte6.parameter_count = 1;
1846 command_que_value = tw_dev->command_packet_physical_address[request_id];
1847 if (command_que_value == 0) {
1848 printk(KERN_WARNING "3w-xxxx: tw_scsiop_synchronize_cache(): Bad command packet physical address.\n");
1849 return 1;
1850 }
1851
1852
1853 tw_post_command_packet(tw_dev, request_id);
1854
1855 return 0;
1856}
1857
1858
1859static int tw_scsiop_test_unit_ready(TW_Device_Extension *tw_dev, int request_id)
1860{
1861 TW_Param *param;
1862 TW_Command *command_packet;
1863 unsigned long command_que_value;
1864 unsigned long param_value;
1865
1866 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_test_unit_ready()\n");
1867
1868
1869 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
1870 if (command_packet == NULL) {
1871 printk(KERN_WARNING "3w-xxxx: tw_scsiop_test_unit_ready(): Bad command packet virtual address.\n");
1872 return 1;
1873 }
1874 memset(command_packet, 0, sizeof(TW_Sector));
1875 command_packet->opcode__sgloffset = TW_OPSGL_IN(2, TW_OP_GET_PARAM);
1876 command_packet->size = 4;
1877 command_packet->request_id = request_id;
1878 command_packet->status = 0;
1879 command_packet->flags = 0;
1880 command_packet->byte6.parameter_count = 1;
1881
1882
1883 if (tw_dev->alignment_virtual_address[request_id] == NULL) {
1884 printk(KERN_WARNING "3w-xxxx: tw_scsiop_test_unit_ready(): Bad alignment virtual address.\n");
1885 return 1;
1886 }
1887 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
1888 memset(param, 0, sizeof(TW_Sector));
1889 param->table_id = 3;
1890 param->parameter_id = 3;
1891 param->parameter_size_bytes = TW_MAX_UNITS;
1892 param_value = tw_dev->alignment_physical_address[request_id];
1893 if (param_value == 0) {
1894 printk(KERN_WARNING "3w-xxxx: tw_scsiop_test_unit_ready(): Bad alignment physical address.\n");
1895 return 1;
1896 }
1897
1898 command_packet->byte8.param.sgl[0].address = param_value;
1899 command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
1900 command_que_value = tw_dev->command_packet_physical_address[request_id];
1901 if (command_que_value == 0) {
1902 printk(KERN_WARNING "3w-xxxx: tw_scsiop_test_unit_ready(): Bad command packet physical address.\n");
1903 return 1;
1904 }
1905
1906
1907 tw_post_command_packet(tw_dev, request_id);
1908
1909 return 0;
1910}
1911
1912
1913static int tw_scsiop_test_unit_ready_complete(TW_Device_Extension *tw_dev, int request_id)
1914{
1915 unsigned char *is_unit_present;
1916 TW_Param *param;
1917
1918 dprintk(KERN_WARNING "3w-xxxx: tw_scsiop_test_unit_ready_complete()\n");
1919
1920 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
1921 if (param == NULL) {
1922 printk(KERN_WARNING "3w-xxxx: tw_scsiop_test_unit_ready_complete(): Bad alignment virtual address.\n");
1923 return 1;
1924 }
1925 is_unit_present = &(param->data[0]);
1926
1927 if (is_unit_present[tw_dev->srb[request_id]->device->id] & TW_UNIT_ONLINE) {
1928 tw_dev->is_unit_present[tw_dev->srb[request_id]->device->id] = 1;
1929 } else {
1930 tw_dev->is_unit_present[tw_dev->srb[request_id]->device->id] = 0;
1931 tw_dev->srb[request_id]->result = (DID_BAD_TARGET << 16);
1932 return TW_ISR_DONT_RESULT;
1933 }
1934
1935 return 0;
1936}
1937
1938
1939static int tw_scsi_queue(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
1940{
1941 unsigned char *command = SCpnt->cmnd;
1942 int request_id = 0;
1943 int retval = 1;
1944 TW_Device_Extension *tw_dev = (TW_Device_Extension *)SCpnt->device->host->hostdata;
1945
1946
1947 if (test_bit(TW_IN_RESET, &tw_dev->flags))
1948 return SCSI_MLQUEUE_HOST_BUSY;
1949
1950
1951 SCpnt->scsi_done = done;
1952
1953
1954 tw_state_request_start(tw_dev, &request_id);
1955
1956
1957 tw_dev->srb[request_id] = SCpnt;
1958
1959
1960 SCpnt->SCp.phase = TW_PHASE_INITIAL;
1961
1962 switch (*command) {
1963 case READ_10:
1964 case READ_6:
1965 case WRITE_10:
1966 case WRITE_6:
1967 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught READ/WRITE.\n");
1968 retval = tw_scsiop_read_write(tw_dev, request_id);
1969 break;
1970 case TEST_UNIT_READY:
1971 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught TEST_UNIT_READY.\n");
1972 retval = tw_scsiop_test_unit_ready(tw_dev, request_id);
1973 break;
1974 case INQUIRY:
1975 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught INQUIRY.\n");
1976 retval = tw_scsiop_inquiry(tw_dev, request_id);
1977 break;
1978 case READ_CAPACITY:
1979 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught READ_CAPACITY.\n");
1980 retval = tw_scsiop_read_capacity(tw_dev, request_id);
1981 break;
1982 case REQUEST_SENSE:
1983 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught REQUEST_SENSE.\n");
1984 retval = tw_scsiop_request_sense(tw_dev, request_id);
1985 break;
1986 case MODE_SENSE:
1987 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught MODE_SENSE.\n");
1988 retval = tw_scsiop_mode_sense(tw_dev, request_id);
1989 break;
1990 case SYNCHRONIZE_CACHE:
1991 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught SYNCHRONIZE_CACHE.\n");
1992 retval = tw_scsiop_synchronize_cache(tw_dev, request_id);
1993 break;
1994 case TW_IOCTL:
1995 printk(KERN_WARNING "3w-xxxx: SCSI_IOCTL_SEND_COMMAND deprecated, please update your 3ware tools.\n");
1996 break;
1997 default:
1998 printk(KERN_NOTICE "3w-xxxx: scsi%d: Unknown scsi opcode: 0x%x\n", tw_dev->host->host_no, *command);
1999 tw_dev->state[request_id] = TW_S_COMPLETED;
2000 tw_state_request_finish(tw_dev, request_id);
2001 SCpnt->result = (DID_BAD_TARGET << 16);
2002 done(SCpnt);
2003 retval = 0;
2004 }
2005 if (retval) {
2006 tw_dev->state[request_id] = TW_S_COMPLETED;
2007 tw_state_request_finish(tw_dev, request_id);
2008 SCpnt->result = (DID_ERROR << 16);
2009 done(SCpnt);
2010 retval = 0;
2011 }
2012 return retval;
2013}
2014
2015
2016static irqreturn_t tw_interrupt(int irq, void *dev_instance)
2017{
2018 int request_id;
2019 u32 status_reg_value;
2020 TW_Device_Extension *tw_dev = (TW_Device_Extension *)dev_instance;
2021 TW_Response_Queue response_que;
2022 int error = 0, retval = 0;
2023 TW_Command *command_packet;
2024 int handled = 0;
2025
2026
2027 spin_lock(tw_dev->host->host_lock);
2028
2029
2030 status_reg_value = inl(TW_STATUS_REG_ADDR(tw_dev));
2031
2032
2033 if (!(status_reg_value & TW_STATUS_VALID_INTERRUPT))
2034 goto tw_interrupt_bail;
2035
2036 handled = 1;
2037
2038
2039 if (test_bit(TW_IN_RESET, &tw_dev->flags))
2040 goto tw_interrupt_bail;
2041
2042
2043 if (tw_check_bits(status_reg_value)) {
2044 dprintk(KERN_WARNING "3w-xxxx: tw_interrupt(): Unexpected bits.\n");
2045 if (tw_decode_bits(tw_dev, status_reg_value, 1)) {
2046 TW_CLEAR_ALL_INTERRUPTS(tw_dev);
2047 goto tw_interrupt_bail;
2048 }
2049 }
2050
2051
2052 if (status_reg_value & TW_STATUS_HOST_INTERRUPT) {
2053 dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): Received host interrupt.\n");
2054 TW_CLEAR_HOST_INTERRUPT(tw_dev);
2055 }
2056
2057
2058 if (status_reg_value & TW_STATUS_ATTENTION_INTERRUPT) {
2059 dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): Received attention interrupt.\n");
2060 TW_CLEAR_ATTENTION_INTERRUPT(tw_dev);
2061 tw_state_request_start(tw_dev, &request_id);
2062 error = tw_aen_read_queue(tw_dev, request_id);
2063 if (error) {
2064 printk(KERN_WARNING "3w-xxxx: scsi%d: Error reading aen queue.\n", tw_dev->host->host_no);
2065 tw_dev->state[request_id] = TW_S_COMPLETED;
2066 tw_state_request_finish(tw_dev, request_id);
2067 }
2068 }
2069
2070
2071 if (status_reg_value & TW_STATUS_COMMAND_INTERRUPT) {
2072
2073 while (tw_dev->pending_request_count > 0) {
2074 request_id = tw_dev->pending_queue[tw_dev->pending_head];
2075 if (tw_dev->state[request_id] != TW_S_PENDING) {
2076 printk(KERN_WARNING "3w-xxxx: scsi%d: Found request id that wasn't pending.\n", tw_dev->host->host_no);
2077 break;
2078 }
2079 if (tw_post_command_packet(tw_dev, request_id)==0) {
2080 if (tw_dev->pending_head == TW_Q_LENGTH-1) {
2081 tw_dev->pending_head = TW_Q_START;
2082 } else {
2083 tw_dev->pending_head = tw_dev->pending_head + 1;
2084 }
2085 tw_dev->pending_request_count--;
2086 } else {
2087
2088 break;
2089 }
2090 }
2091
2092 if (tw_dev->pending_request_count == 0)
2093 TW_MASK_COMMAND_INTERRUPT(tw_dev);
2094 }
2095
2096
2097 if (status_reg_value & TW_STATUS_RESPONSE_INTERRUPT) {
2098
2099 while ((status_reg_value & TW_STATUS_RESPONSE_QUEUE_EMPTY) == 0) {
2100
2101 response_que.value = inl(TW_RESPONSE_QUEUE_REG_ADDR(tw_dev));
2102 request_id = TW_RESID_OUT(response_que.response_id);
2103 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
2104 error = 0;
2105
2106
2107 if (command_packet->status != 0) {
2108
2109 if (tw_dev->srb[request_id] == NULL) {
2110 tw_decode_sense(tw_dev, request_id, 0);
2111 } else {
2112 error = tw_decode_sense(tw_dev, request_id, 1);
2113 }
2114 }
2115
2116
2117 if (tw_dev->state[request_id] != TW_S_POSTED) {
2118 if (tw_dev->srb[request_id] != NULL) {
2119 printk(KERN_WARNING "3w-xxxx: scsi%d: Received a request id that wasn't posted.\n", tw_dev->host->host_no);
2120 error = 1;
2121 }
2122 }
2123
2124 dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): Response queue request id: %d.\n", request_id);
2125
2126
2127 if (tw_dev->srb[request_id] == NULL) {
2128 dprintk(KERN_WARNING "3w-xxxx: tw_interrupt(): Found internally posted command.\n");
2129
2130 if (request_id != tw_dev->chrdev_request_id) {
2131 retval = tw_aen_complete(tw_dev, request_id);
2132 if (retval) {
2133 printk(KERN_WARNING "3w-xxxx: scsi%d: Error completing aen.\n", tw_dev->host->host_no);
2134 }
2135 } else {
2136 tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE;
2137 wake_up(&tw_dev->ioctl_wqueue);
2138 }
2139 } else {
2140 switch (tw_dev->srb[request_id]->cmnd[0]) {
2141 case READ_10:
2142 case READ_6:
2143 dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught READ_10/READ_6\n");
2144 break;
2145 case WRITE_10:
2146 case WRITE_6:
2147 dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught WRITE_10/WRITE_6\n");
2148 break;
2149 case TEST_UNIT_READY:
2150 dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught TEST_UNIT_READY\n");
2151 error = tw_scsiop_test_unit_ready_complete(tw_dev, request_id);
2152 break;
2153 case INQUIRY:
2154 dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught INQUIRY\n");
2155 error = tw_scsiop_inquiry_complete(tw_dev, request_id);
2156 break;
2157 case READ_CAPACITY:
2158 dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught READ_CAPACITY\n");
2159 error = tw_scsiop_read_capacity_complete(tw_dev, request_id);
2160 break;
2161 case MODE_SENSE:
2162 dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught MODE_SENSE\n");
2163 error = tw_scsiop_mode_sense_complete(tw_dev, request_id);
2164 break;
2165 case SYNCHRONIZE_CACHE:
2166 dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught SYNCHRONIZE_CACHE\n");
2167 break;
2168 default:
2169 printk(KERN_WARNING "3w-xxxx: case slip in tw_interrupt()\n");
2170 error = 1;
2171 }
2172
2173
2174 if (error == 0) {
2175 tw_dev->srb[request_id]->result = (DID_OK << 16);
2176 }
2177
2178
2179 if (error == 1) {
2180
2181 tw_dev->srb[request_id]->result = (DID_OK << 16) | (CHECK_CONDITION << 1);
2182 }
2183
2184
2185 if ((error != TW_ISR_DONT_COMPLETE)) {
2186 tw_dev->state[request_id] = TW_S_COMPLETED;
2187 tw_state_request_finish(tw_dev, request_id);
2188 tw_dev->posted_request_count--;
2189 tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
2190
2191 tw_unmap_scsi_data(tw_dev->tw_pci_dev, tw_dev->srb[request_id]);
2192 }
2193 }
2194
2195
2196 status_reg_value = inl(TW_STATUS_REG_ADDR(tw_dev));
2197 if (tw_check_bits(status_reg_value)) {
2198 dprintk(KERN_WARNING "3w-xxxx: tw_interrupt(): Unexpected bits.\n");
2199 if (tw_decode_bits(tw_dev, status_reg_value, 1)) {
2200 TW_CLEAR_ALL_INTERRUPTS(tw_dev);
2201 goto tw_interrupt_bail;
2202 }
2203 }
2204 }
2205 }
2206
2207tw_interrupt_bail:
2208 spin_unlock(tw_dev->host->host_lock);
2209 return IRQ_RETVAL(handled);
2210}
2211
2212
2213static void __tw_shutdown(TW_Device_Extension *tw_dev)
2214{
2215
2216 TW_DISABLE_INTERRUPTS(tw_dev);
2217
2218
2219 free_irq(tw_dev->tw_pci_dev->irq, tw_dev);
2220
2221 printk(KERN_WARNING "3w-xxxx: Shutting down host %d.\n", tw_dev->host->host_no);
2222
2223
2224 if (tw_initconnection(tw_dev, 1)) {
2225 printk(KERN_WARNING "3w-xxxx: Connection shutdown failed.\n");
2226 } else {
2227 printk(KERN_WARNING "3w-xxxx: Shutdown complete.\n");
2228 }
2229
2230
2231 TW_ENABLE_AND_CLEAR_INTERRUPTS(tw_dev);
2232}
2233
2234
2235static void tw_shutdown(struct pci_dev *pdev)
2236{
2237 struct Scsi_Host *host = pci_get_drvdata(pdev);
2238 TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata;
2239
2240 __tw_shutdown(tw_dev);
2241}
2242
2243static struct scsi_host_template driver_template = {
2244 .module = THIS_MODULE,
2245 .name = "3ware Storage Controller",
2246 .queuecommand = tw_scsi_queue,
2247 .eh_host_reset_handler = tw_scsi_eh_reset,
2248 .bios_param = tw_scsi_biosparam,
2249 .change_queue_depth = tw_change_queue_depth,
2250 .can_queue = TW_Q_LENGTH-2,
2251 .this_id = -1,
2252 .sg_tablesize = TW_MAX_SGL_LENGTH,
2253 .max_sectors = TW_MAX_SECTORS,
2254 .cmd_per_lun = TW_MAX_CMDS_PER_LUN,
2255 .use_clustering = ENABLE_CLUSTERING,
2256 .shost_attrs = tw_host_attrs,
2257 .emulated = 1
2258};
2259
2260
2261static int __devinit tw_probe(struct pci_dev *pdev, const struct pci_device_id *dev_id)
2262{
2263 struct Scsi_Host *host = NULL;
2264 TW_Device_Extension *tw_dev;
2265 int retval = -ENODEV;
2266
2267 retval = pci_enable_device(pdev);
2268 if (retval) {
2269 printk(KERN_WARNING "3w-xxxx: Failed to enable pci device.");
2270 goto out_disable_device;
2271 }
2272
2273 pci_set_master(pdev);
2274
2275 retval = pci_set_dma_mask(pdev, TW_DMA_MASK);
2276 if (retval) {
2277 printk(KERN_WARNING "3w-xxxx: Failed to set dma mask.");
2278 goto out_disable_device;
2279 }
2280
2281 host = scsi_host_alloc(&driver_template, sizeof(TW_Device_Extension));
2282 if (!host) {
2283 printk(KERN_WARNING "3w-xxxx: Failed to allocate memory for device extension.");
2284 retval = -ENOMEM;
2285 goto out_disable_device;
2286 }
2287 tw_dev = (TW_Device_Extension *)host->hostdata;
2288
2289
2290 tw_dev->host = host;
2291 tw_dev->tw_pci_dev = pdev;
2292
2293 if (tw_initialize_device_extension(tw_dev)) {
2294 printk(KERN_WARNING "3w-xxxx: Failed to initialize device extension.");
2295 goto out_free_device_extension;
2296 }
2297
2298
2299 retval = pci_request_regions(pdev, "3w-xxxx");
2300 if (retval) {
2301 printk(KERN_WARNING "3w-xxxx: Failed to get mem region.");
2302 goto out_free_device_extension;
2303 }
2304
2305
2306 tw_dev->base_addr = pci_resource_start(pdev, 0);
2307 if (!tw_dev->base_addr) {
2308 printk(KERN_WARNING "3w-xxxx: Failed to get io address.");
2309 goto out_release_mem_region;
2310 }
2311
2312
2313 TW_DISABLE_INTERRUPTS(tw_dev);
2314
2315
2316 if (tw_reset_sequence(tw_dev))
2317 goto out_release_mem_region;
2318
2319
2320 host->max_id = TW_MAX_UNITS;
2321 host->max_cmd_len = TW_MAX_CDB_LEN;
2322
2323
2324 host->max_lun = 0;
2325 host->max_channel = 0;
2326
2327
2328 retval = scsi_add_host(host, &pdev->dev);
2329 if (retval) {
2330 printk(KERN_WARNING "3w-xxxx: scsi add host failed");
2331 goto out_release_mem_region;
2332 }
2333
2334 pci_set_drvdata(pdev, host);
2335
2336 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);
2337
2338
2339 retval = request_irq(pdev->irq, tw_interrupt, IRQF_SHARED, "3w-xxxx", tw_dev);
2340 if (retval) {
2341 printk(KERN_WARNING "3w-xxxx: Error requesting IRQ.");
2342 goto out_remove_host;
2343 }
2344
2345 tw_device_extension_list[tw_device_extension_count] = tw_dev;
2346 tw_device_extension_count++;
2347
2348
2349 TW_ENABLE_AND_CLEAR_INTERRUPTS(tw_dev);
2350
2351
2352 scsi_scan_host(host);
2353
2354 if (twe_major == -1) {
2355 if ((twe_major = register_chrdev (0, "twe", &tw_fops)) < 0)
2356 printk(KERN_WARNING "3w-xxxx: Failed to register character device.");
2357 }
2358 return 0;
2359
2360out_remove_host:
2361 scsi_remove_host(host);
2362out_release_mem_region:
2363 pci_release_regions(pdev);
2364out_free_device_extension:
2365 tw_free_device_extension(tw_dev);
2366 scsi_host_put(host);
2367out_disable_device:
2368 pci_disable_device(pdev);
2369
2370 return retval;
2371}
2372
2373
2374static void tw_remove(struct pci_dev *pdev)
2375{
2376 struct Scsi_Host *host = pci_get_drvdata(pdev);
2377 TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata;
2378
2379 scsi_remove_host(tw_dev->host);
2380
2381
2382 if (twe_major >= 0) {
2383 unregister_chrdev(twe_major, "twe");
2384 twe_major = -1;
2385 }
2386
2387
2388 __tw_shutdown(tw_dev);
2389
2390
2391 pci_release_regions(pdev);
2392
2393
2394 tw_free_device_extension(tw_dev);
2395
2396 scsi_host_put(tw_dev->host);
2397 pci_disable_device(pdev);
2398 tw_device_extension_count--;
2399}
2400
2401
2402static struct pci_device_id tw_pci_tbl[] __devinitdata = {
2403 { PCI_VENDOR_ID_3WARE, PCI_DEVICE_ID_3WARE_1000,
2404 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
2405 { PCI_VENDOR_ID_3WARE, PCI_DEVICE_ID_3WARE_7000,
2406 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
2407 { }
2408};
2409MODULE_DEVICE_TABLE(pci, tw_pci_tbl);
2410
2411
2412static struct pci_driver tw_driver = {
2413 .name = "3w-xxxx",
2414 .id_table = tw_pci_tbl,
2415 .probe = tw_probe,
2416 .remove = tw_remove,
2417 .shutdown = tw_shutdown,
2418};
2419
2420
2421static int __init tw_init(void)
2422{
2423 printk(KERN_WARNING "3ware Storage Controller device driver for Linux v%s.\n", TW_DRIVER_VERSION);
2424
2425 return pci_register_driver(&tw_driver);
2426}
2427
2428
2429static void __exit tw_exit(void)
2430{
2431 pci_unregister_driver(&tw_driver);
2432}
2433
2434module_init(tw_init);
2435module_exit(tw_exit);
2436
2437