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