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#include <linux/module.h>
81#include <linux/reboot.h>
82#include <linux/spinlock.h>
83#include <linux/interrupt.h>
84#include <linux/moduleparam.h>
85#include <linux/errno.h>
86#include <linux/types.h>
87#include <linux/delay.h>
88#include <linux/pci.h>
89#include <linux/time.h>
90#include <linux/mutex.h>
91#include <linux/smp_lock.h>
92#include <asm/io.h>
93#include <asm/irq.h>
94#include <asm/uaccess.h>
95#include <scsi/scsi.h>
96#include <scsi/scsi_host.h>
97#include <scsi/scsi_tcq.h>
98#include <scsi/scsi_cmnd.h>
99#include "3w-9xxx.h"
100
101
102#define TW_DRIVER_VERSION "2.26.02.011"
103static TW_Device_Extension *twa_device_extension_list[TW_MAX_SLOT];
104static unsigned int twa_device_extension_count;
105static int twa_major = -1;
106extern struct timezone sys_tz;
107
108
109MODULE_AUTHOR ("AMCC");
110MODULE_DESCRIPTION ("3ware 9000 Storage Controller Linux Driver");
111MODULE_LICENSE("GPL");
112MODULE_VERSION(TW_DRIVER_VERSION);
113
114static int use_msi = 0;
115module_param(use_msi, int, S_IRUGO);
116MODULE_PARM_DESC(use_msi, "Use Message Signaled Interrupts. Default: 0");
117
118
119static void twa_aen_queue_event(TW_Device_Extension *tw_dev, TW_Command_Apache_Header *header);
120static int twa_aen_read_queue(TW_Device_Extension *tw_dev, int request_id);
121static char *twa_aen_severity_lookup(unsigned char severity_code);
122static void twa_aen_sync_time(TW_Device_Extension *tw_dev, int request_id);
123static int twa_chrdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);
124static int twa_chrdev_open(struct inode *inode, struct file *file);
125static int twa_fill_sense(TW_Device_Extension *tw_dev, int request_id, int copy_sense, int print_host);
126static void twa_free_request_id(TW_Device_Extension *tw_dev,int request_id);
127static void twa_get_request_id(TW_Device_Extension *tw_dev, int *request_id);
128static int twa_initconnection(TW_Device_Extension *tw_dev, int message_credits,
129 u32 set_features, unsigned short current_fw_srl,
130 unsigned short current_fw_arch_id,
131 unsigned short current_fw_branch,
132 unsigned short current_fw_build,
133 unsigned short *fw_on_ctlr_srl,
134 unsigned short *fw_on_ctlr_arch_id,
135 unsigned short *fw_on_ctlr_branch,
136 unsigned short *fw_on_ctlr_build,
137 u32 *init_connect_result);
138static void twa_load_sgl(TW_Device_Extension *tw_dev, TW_Command_Full *full_command_packet, int request_id, dma_addr_t dma_handle, int length);
139static int twa_poll_response(TW_Device_Extension *tw_dev, int request_id, int seconds);
140static int twa_poll_status_gone(TW_Device_Extension *tw_dev, u32 flag, int seconds);
141static int twa_post_command_packet(TW_Device_Extension *tw_dev, int request_id, char internal);
142static int twa_reset_device_extension(TW_Device_Extension *tw_dev);
143static int twa_reset_sequence(TW_Device_Extension *tw_dev, int soft_reset);
144static int twa_scsiop_execute_scsi(TW_Device_Extension *tw_dev, int request_id, char *cdb, int use_sg, TW_SG_Entry *sglistarg);
145static void twa_scsiop_execute_scsi_complete(TW_Device_Extension *tw_dev, int request_id);
146static char *twa_string_lookup(twa_message_type *table, unsigned int aen_code);
147static void twa_unmap_scsi_data(TW_Device_Extension *tw_dev, int request_id);
148
149
150
151
152static ssize_t twa_show_stats(struct device *dev,
153 struct device_attribute *attr, char *buf)
154{
155 struct Scsi_Host *host = class_to_shost(dev);
156 TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata;
157 unsigned long flags = 0;
158 ssize_t len;
159
160 spin_lock_irqsave(tw_dev->host->host_lock, flags);
161 len = snprintf(buf, PAGE_SIZE, "3w-9xxx Driver version: %s\n"
162 "Current commands posted: %4d\n"
163 "Max commands posted: %4d\n"
164 "Current pending commands: %4d\n"
165 "Max pending commands: %4d\n"
166 "Last sgl length: %4d\n"
167 "Max sgl length: %4d\n"
168 "Last sector count: %4d\n"
169 "Max sector count: %4d\n"
170 "SCSI Host Resets: %4d\n"
171 "AEN's: %4d\n",
172 TW_DRIVER_VERSION,
173 tw_dev->posted_request_count,
174 tw_dev->max_posted_request_count,
175 tw_dev->pending_request_count,
176 tw_dev->max_pending_request_count,
177 tw_dev->sgl_entries,
178 tw_dev->max_sgl_entries,
179 tw_dev->sector_count,
180 tw_dev->max_sector_count,
181 tw_dev->num_resets,
182 tw_dev->aen_count);
183 spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
184 return len;
185}
186
187
188static int twa_change_queue_depth(struct scsi_device *sdev, int queue_depth)
189{
190 if (queue_depth > TW_Q_LENGTH-2)
191 queue_depth = TW_Q_LENGTH-2;
192 scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG, queue_depth);
193 return queue_depth;
194}
195
196
197static struct device_attribute twa_host_stats_attr = {
198 .attr = {
199 .name = "stats",
200 .mode = S_IRUGO,
201 },
202 .show = twa_show_stats
203};
204
205
206static struct device_attribute *twa_host_attrs[] = {
207 &twa_host_stats_attr,
208 NULL,
209};
210
211
212static const struct file_operations twa_fops = {
213 .owner = THIS_MODULE,
214 .ioctl = twa_chrdev_ioctl,
215 .open = twa_chrdev_open,
216 .release = NULL
217};
218
219
220static int twa_aen_complete(TW_Device_Extension *tw_dev, int request_id)
221{
222 TW_Command_Full *full_command_packet;
223 TW_Command *command_packet;
224 TW_Command_Apache_Header *header;
225 unsigned short aen;
226 int retval = 1;
227
228 header = (TW_Command_Apache_Header *)tw_dev->generic_buffer_virt[request_id];
229 tw_dev->posted_request_count--;
230 aen = le16_to_cpu(header->status_block.error);
231 full_command_packet = tw_dev->command_packet_virt[request_id];
232 command_packet = &full_command_packet->command.oldcommand;
233
234
235 if (TW_OP_OUT(command_packet->opcode__sgloffset) == TW_OP_SET_PARAM) {
236
237 if (twa_aen_read_queue(tw_dev, request_id))
238 goto out2;
239 else {
240 retval = 0;
241 goto out;
242 }
243 }
244
245 switch (aen) {
246 case TW_AEN_QUEUE_EMPTY:
247
248 break;
249 case TW_AEN_SYNC_TIME_WITH_HOST:
250 twa_aen_sync_time(tw_dev, request_id);
251 retval = 0;
252 goto out;
253 default:
254 twa_aen_queue_event(tw_dev, header);
255
256
257 if (twa_aen_read_queue(tw_dev, request_id))
258 goto out2;
259 else {
260 retval = 0;
261 goto out;
262 }
263 }
264 retval = 0;
265out2:
266 tw_dev->state[request_id] = TW_S_COMPLETED;
267 twa_free_request_id(tw_dev, request_id);
268 clear_bit(TW_IN_ATTENTION_LOOP, &tw_dev->flags);
269out:
270 return retval;
271}
272
273
274static int twa_aen_drain_queue(TW_Device_Extension *tw_dev, int no_check_reset)
275{
276 int request_id = 0;
277 char cdb[TW_MAX_CDB_LEN];
278 TW_SG_Entry sglist[1];
279 int finished = 0, count = 0;
280 TW_Command_Full *full_command_packet;
281 TW_Command_Apache_Header *header;
282 unsigned short aen;
283 int first_reset = 0, queue = 0, retval = 1;
284
285 if (no_check_reset)
286 first_reset = 0;
287 else
288 first_reset = 1;
289
290 full_command_packet = tw_dev->command_packet_virt[request_id];
291 memset(full_command_packet, 0, sizeof(TW_Command_Full));
292
293
294 memset(&cdb, 0, TW_MAX_CDB_LEN);
295 cdb[0] = REQUEST_SENSE;
296 cdb[4] = TW_ALLOCATION_LENGTH;
297
298
299 memset(&sglist, 0, sizeof(TW_SG_Entry));
300 sglist[0].length = TW_SECTOR_SIZE;
301 sglist[0].address = tw_dev->generic_buffer_phys[request_id];
302
303 if (sglist[0].address & TW_ALIGNMENT_9000_SGL) {
304 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1, "Found unaligned address during AEN drain");
305 goto out;
306 }
307
308
309 tw_dev->srb[request_id] = NULL;
310
311 do {
312
313 if (twa_scsiop_execute_scsi(tw_dev, request_id, cdb, 1, sglist)) {
314 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x2, "Error posting request sense");
315 goto out;
316 }
317
318
319 if (twa_poll_response(tw_dev, request_id, 30)) {
320 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x3, "No valid response while draining AEN queue");
321 tw_dev->posted_request_count--;
322 goto out;
323 }
324
325 tw_dev->posted_request_count--;
326 header = (TW_Command_Apache_Header *)tw_dev->generic_buffer_virt[request_id];
327 aen = le16_to_cpu(header->status_block.error);
328 queue = 0;
329 count++;
330
331 switch (aen) {
332 case TW_AEN_QUEUE_EMPTY:
333 if (first_reset != 1)
334 goto out;
335 else
336 finished = 1;
337 break;
338 case TW_AEN_SOFT_RESET:
339 if (first_reset == 0)
340 first_reset = 1;
341 else
342 queue = 1;
343 break;
344 case TW_AEN_SYNC_TIME_WITH_HOST:
345 break;
346 default:
347 queue = 1;
348 }
349
350
351 if (queue)
352 twa_aen_queue_event(tw_dev, header);
353 } while ((finished == 0) && (count < TW_MAX_AEN_DRAIN));
354
355 if (count == TW_MAX_AEN_DRAIN)
356 goto out;
357
358 retval = 0;
359out:
360 tw_dev->state[request_id] = TW_S_INITIAL;
361 return retval;
362}
363
364
365static void twa_aen_queue_event(TW_Device_Extension *tw_dev, TW_Command_Apache_Header *header)
366{
367 u32 local_time;
368 struct timeval time;
369 TW_Event *event;
370 unsigned short aen;
371 char host[16];
372 char *error_str;
373
374 tw_dev->aen_count++;
375
376
377 event = tw_dev->event_queue[tw_dev->error_index];
378
379
380 host[0] = '\0';
381 if (tw_dev->host) {
382 sprintf(host, " scsi%d:", tw_dev->host->host_no);
383 if (event->retrieved == TW_AEN_NOT_RETRIEVED)
384 tw_dev->aen_clobber = 1;
385 }
386
387 aen = le16_to_cpu(header->status_block.error);
388 memset(event, 0, sizeof(TW_Event));
389
390 event->severity = TW_SEV_OUT(header->status_block.severity__reserved);
391 do_gettimeofday(&time);
392 local_time = (u32)(time.tv_sec - (sys_tz.tz_minuteswest * 60));
393 event->time_stamp_sec = local_time;
394 event->aen_code = aen;
395 event->retrieved = TW_AEN_NOT_RETRIEVED;
396 event->sequence_id = tw_dev->error_sequence_id;
397 tw_dev->error_sequence_id++;
398
399
400 error_str = &(header->err_specific_desc[strlen(header->err_specific_desc)+1]);
401
402 header->err_specific_desc[sizeof(header->err_specific_desc) - 1] = '\0';
403 event->parameter_len = strlen(header->err_specific_desc);
404 memcpy(event->parameter_data, header->err_specific_desc, event->parameter_len + (error_str[0] == '\0' ? 0 : (1 + strlen(error_str))));
405 if (event->severity != TW_AEN_SEVERITY_DEBUG)
406 printk(KERN_WARNING "3w-9xxx:%s AEN: %s (0x%02X:0x%04X): %s:%s.\n",
407 host,
408 twa_aen_severity_lookup(TW_SEV_OUT(header->status_block.severity__reserved)),
409 TW_MESSAGE_SOURCE_CONTROLLER_EVENT, aen,
410 error_str[0] == '\0' ? twa_string_lookup(twa_aen_table, aen) : error_str,
411 header->err_specific_desc);
412 else
413 tw_dev->aen_count--;
414
415 if ((tw_dev->error_index + 1) == TW_Q_LENGTH)
416 tw_dev->event_queue_wrapped = 1;
417 tw_dev->error_index = (tw_dev->error_index + 1 ) % TW_Q_LENGTH;
418}
419
420
421static int twa_aen_read_queue(TW_Device_Extension *tw_dev, int request_id)
422{
423 char cdb[TW_MAX_CDB_LEN];
424 TW_SG_Entry sglist[1];
425 TW_Command_Full *full_command_packet;
426 int retval = 1;
427
428 full_command_packet = tw_dev->command_packet_virt[request_id];
429 memset(full_command_packet, 0, sizeof(TW_Command_Full));
430
431
432 memset(&cdb, 0, TW_MAX_CDB_LEN);
433 cdb[0] = REQUEST_SENSE;
434 cdb[4] = TW_ALLOCATION_LENGTH;
435
436
437 memset(&sglist, 0, sizeof(TW_SG_Entry));
438 sglist[0].length = TW_SECTOR_SIZE;
439 sglist[0].address = tw_dev->generic_buffer_phys[request_id];
440
441
442 tw_dev->srb[request_id] = NULL;
443
444
445 if (twa_scsiop_execute_scsi(tw_dev, request_id, cdb, 1, sglist)) {
446 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x4, "Post failed while reading AEN queue");
447 goto out;
448 }
449 retval = 0;
450out:
451 return retval;
452}
453
454
455static char *twa_aen_severity_lookup(unsigned char severity_code)
456{
457 char *retval = NULL;
458
459 if ((severity_code < (unsigned char) TW_AEN_SEVERITY_ERROR) ||
460 (severity_code > (unsigned char) TW_AEN_SEVERITY_DEBUG))
461 goto out;
462
463 retval = twa_aen_severity_table[severity_code];
464out:
465 return retval;
466}
467
468
469static void twa_aen_sync_time(TW_Device_Extension *tw_dev, int request_id)
470{
471 u32 schedulertime;
472 struct timeval utc;
473 TW_Command_Full *full_command_packet;
474 TW_Command *command_packet;
475 TW_Param_Apache *param;
476 u32 local_time;
477
478
479 full_command_packet = tw_dev->command_packet_virt[request_id];
480 memset(full_command_packet, 0, sizeof(TW_Command_Full));
481 command_packet = &full_command_packet->command.oldcommand;
482 command_packet->opcode__sgloffset = TW_OPSGL_IN(2, TW_OP_SET_PARAM);
483 command_packet->request_id = request_id;
484 command_packet->byte8_offset.param.sgl[0].address = TW_CPU_TO_SGL(tw_dev->generic_buffer_phys[request_id]);
485 command_packet->byte8_offset.param.sgl[0].length = cpu_to_le32(TW_SECTOR_SIZE);
486 command_packet->size = TW_COMMAND_SIZE;
487 command_packet->byte6_offset.parameter_count = cpu_to_le16(1);
488
489
490 param = (TW_Param_Apache *)tw_dev->generic_buffer_virt[request_id];
491 memset(param, 0, TW_SECTOR_SIZE);
492 param->table_id = cpu_to_le16(TW_TIMEKEEP_TABLE | 0x8000);
493 param->parameter_id = cpu_to_le16(0x3);
494 param->parameter_size_bytes = cpu_to_le16(4);
495
496
497
498 do_gettimeofday(&utc);
499 local_time = (u32)(utc.tv_sec - (sys_tz.tz_minuteswest * 60));
500 schedulertime = local_time - (3 * 86400);
501 schedulertime = cpu_to_le32(schedulertime % 604800);
502
503 memcpy(param->data, &schedulertime, sizeof(u32));
504
505
506 tw_dev->srb[request_id] = NULL;
507
508
509 twa_post_command_packet(tw_dev, request_id, 1);
510}
511
512
513static int twa_allocate_memory(TW_Device_Extension *tw_dev, int size, int which)
514{
515 int i;
516 dma_addr_t dma_handle;
517 unsigned long *cpu_addr;
518 int retval = 1;
519
520 cpu_addr = pci_alloc_consistent(tw_dev->tw_pci_dev, size*TW_Q_LENGTH, &dma_handle);
521 if (!cpu_addr) {
522 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x5, "Memory allocation failed");
523 goto out;
524 }
525
526 if ((unsigned long)cpu_addr % (TW_ALIGNMENT_9000)) {
527 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x6, "Failed to allocate correctly aligned memory");
528 pci_free_consistent(tw_dev->tw_pci_dev, size*TW_Q_LENGTH, cpu_addr, dma_handle);
529 goto out;
530 }
531
532 memset(cpu_addr, 0, size*TW_Q_LENGTH);
533
534 for (i = 0; i < TW_Q_LENGTH; i++) {
535 switch(which) {
536 case 0:
537 tw_dev->command_packet_phys[i] = dma_handle+(i*size);
538 tw_dev->command_packet_virt[i] = (TW_Command_Full *)((unsigned char *)cpu_addr + (i*size));
539 break;
540 case 1:
541 tw_dev->generic_buffer_phys[i] = dma_handle+(i*size);
542 tw_dev->generic_buffer_virt[i] = (unsigned long *)((unsigned char *)cpu_addr + (i*size));
543 break;
544 }
545 }
546 retval = 0;
547out:
548 return retval;
549}
550
551
552static int twa_check_bits(u32 status_reg_value)
553{
554 int retval = 1;
555
556 if ((status_reg_value & TW_STATUS_EXPECTED_BITS) != TW_STATUS_EXPECTED_BITS)
557 goto out;
558 if ((status_reg_value & TW_STATUS_UNEXPECTED_BITS) != 0)
559 goto out;
560
561 retval = 0;
562out:
563 return retval;
564}
565
566
567static int twa_check_srl(TW_Device_Extension *tw_dev, int *flashed)
568{
569 int retval = 1;
570 unsigned short fw_on_ctlr_srl = 0, fw_on_ctlr_arch_id = 0;
571 unsigned short fw_on_ctlr_branch = 0, fw_on_ctlr_build = 0;
572 u32 init_connect_result = 0;
573
574 if (twa_initconnection(tw_dev, TW_INIT_MESSAGE_CREDITS,
575 TW_EXTENDED_INIT_CONNECT, TW_CURRENT_DRIVER_SRL,
576 TW_9000_ARCH_ID, TW_CURRENT_DRIVER_BRANCH,
577 TW_CURRENT_DRIVER_BUILD, &fw_on_ctlr_srl,
578 &fw_on_ctlr_arch_id, &fw_on_ctlr_branch,
579 &fw_on_ctlr_build, &init_connect_result)) {
580 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x7, "Initconnection failed while checking SRL");
581 goto out;
582 }
583
584 tw_dev->tw_compat_info.working_srl = fw_on_ctlr_srl;
585 tw_dev->tw_compat_info.working_branch = fw_on_ctlr_branch;
586 tw_dev->tw_compat_info.working_build = fw_on_ctlr_build;
587
588
589 if (!(init_connect_result & TW_CTLR_FW_COMPATIBLE)) {
590 if (twa_initconnection(tw_dev, TW_INIT_MESSAGE_CREDITS,
591 TW_EXTENDED_INIT_CONNECT,
592 TW_BASE_FW_SRL, TW_9000_ARCH_ID,
593 TW_BASE_FW_BRANCH, TW_BASE_FW_BUILD,
594 &fw_on_ctlr_srl, &fw_on_ctlr_arch_id,
595 &fw_on_ctlr_branch, &fw_on_ctlr_build,
596 &init_connect_result)) {
597 TW_PRINTK(tw_dev->host, TW_DRIVER, 0xa, "Initconnection (base mode) failed while checking SRL");
598 goto out;
599 }
600 if (!(init_connect_result & TW_CTLR_FW_COMPATIBLE)) {
601 if (TW_CURRENT_DRIVER_SRL > fw_on_ctlr_srl) {
602 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x32, "Firmware and driver incompatibility: please upgrade firmware");
603 } else {
604 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x33, "Firmware and driver incompatibility: please upgrade driver");
605 }
606 goto out;
607 }
608 tw_dev->tw_compat_info.working_srl = TW_BASE_FW_SRL;
609 tw_dev->tw_compat_info.working_branch = TW_BASE_FW_BRANCH;
610 tw_dev->tw_compat_info.working_build = TW_BASE_FW_BUILD;
611 }
612
613
614 strncpy(tw_dev->tw_compat_info.driver_version, TW_DRIVER_VERSION, strlen(TW_DRIVER_VERSION));
615 tw_dev->tw_compat_info.driver_srl_high = TW_CURRENT_DRIVER_SRL;
616 tw_dev->tw_compat_info.driver_branch_high = TW_CURRENT_DRIVER_BRANCH;
617 tw_dev->tw_compat_info.driver_build_high = TW_CURRENT_DRIVER_BUILD;
618 tw_dev->tw_compat_info.driver_srl_low = TW_BASE_FW_SRL;
619 tw_dev->tw_compat_info.driver_branch_low = TW_BASE_FW_BRANCH;
620 tw_dev->tw_compat_info.driver_build_low = TW_BASE_FW_BUILD;
621 tw_dev->tw_compat_info.fw_on_ctlr_srl = fw_on_ctlr_srl;
622 tw_dev->tw_compat_info.fw_on_ctlr_branch = fw_on_ctlr_branch;
623 tw_dev->tw_compat_info.fw_on_ctlr_build = fw_on_ctlr_build;
624
625 retval = 0;
626out:
627 return retval;
628}
629
630
631static int twa_chrdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
632{
633 long timeout;
634 unsigned long *cpu_addr, data_buffer_length_adjusted = 0, flags = 0;
635 dma_addr_t dma_handle;
636 int request_id = 0;
637 unsigned int sequence_id = 0;
638 unsigned char event_index, start_index;
639 TW_Ioctl_Driver_Command driver_command;
640 TW_Ioctl_Buf_Apache *tw_ioctl;
641 TW_Lock *tw_lock;
642 TW_Command_Full *full_command_packet;
643 TW_Compatibility_Info *tw_compat_info;
644 TW_Event *event;
645 struct timeval current_time;
646 u32 current_time_ms;
647 TW_Device_Extension *tw_dev = twa_device_extension_list[iminor(inode)];
648 int retval = TW_IOCTL_ERROR_OS_EFAULT;
649 void __user *argp = (void __user *)arg;
650
651
652 if (mutex_lock_interruptible(&tw_dev->ioctl_lock)) {
653 retval = TW_IOCTL_ERROR_OS_EINTR;
654 goto out;
655 }
656
657
658 if (copy_from_user(&driver_command, argp, sizeof(TW_Ioctl_Driver_Command)))
659 goto out2;
660
661
662 if (driver_command.buffer_length > TW_MAX_SECTORS * 2048) {
663 retval = TW_IOCTL_ERROR_OS_EINVAL;
664 goto out2;
665 }
666
667
668 data_buffer_length_adjusted = (driver_command.buffer_length + 511) & ~511;
669
670
671 cpu_addr = dma_alloc_coherent(&tw_dev->tw_pci_dev->dev, data_buffer_length_adjusted+sizeof(TW_Ioctl_Buf_Apache) - 1, &dma_handle, GFP_KERNEL);
672 if (!cpu_addr) {
673 retval = TW_IOCTL_ERROR_OS_ENOMEM;
674 goto out2;
675 }
676
677 tw_ioctl = (TW_Ioctl_Buf_Apache *)cpu_addr;
678
679
680 if (copy_from_user(tw_ioctl, argp, driver_command.buffer_length + sizeof(TW_Ioctl_Buf_Apache) - 1))
681 goto out3;
682
683
684 switch (cmd) {
685 case TW_IOCTL_FIRMWARE_PASS_THROUGH:
686 spin_lock_irqsave(tw_dev->host->host_lock, flags);
687 twa_get_request_id(tw_dev, &request_id);
688
689
690 tw_dev->srb[request_id] = NULL;
691
692
693 tw_dev->chrdev_request_id = request_id;
694
695 full_command_packet = &tw_ioctl->firmware_command;
696
697
698 twa_load_sgl(tw_dev, full_command_packet, request_id, dma_handle, data_buffer_length_adjusted);
699
700 memcpy(tw_dev->command_packet_virt[request_id], &(tw_ioctl->firmware_command), sizeof(TW_Command_Full));
701
702
703 twa_post_command_packet(tw_dev, request_id, 1);
704 spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
705
706 timeout = TW_IOCTL_CHRDEV_TIMEOUT*HZ;
707
708
709 timeout = wait_event_timeout(tw_dev->ioctl_wqueue, tw_dev->chrdev_request_id == TW_IOCTL_CHRDEV_FREE, timeout);
710
711
712 if (tw_dev->chrdev_request_id != TW_IOCTL_CHRDEV_FREE) {
713
714 printk(KERN_WARNING "3w-9xxx: scsi%d: WARNING: (0x%02X:0x%04X): Character ioctl (0x%x) timed out, resetting card.\n",
715 tw_dev->host->host_no, TW_DRIVER, 0x37,
716 cmd);
717 retval = TW_IOCTL_ERROR_OS_EIO;
718 twa_reset_device_extension(tw_dev);
719 goto out3;
720 }
721
722
723 memcpy(&(tw_ioctl->firmware_command), tw_dev->command_packet_virt[request_id], sizeof(TW_Command_Full));
724
725
726 spin_lock_irqsave(tw_dev->host->host_lock, flags);
727 tw_dev->posted_request_count--;
728 tw_dev->state[request_id] = TW_S_COMPLETED;
729 twa_free_request_id(tw_dev, request_id);
730 spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
731 break;
732 case TW_IOCTL_GET_COMPATIBILITY_INFO:
733 tw_ioctl->driver_command.status = 0;
734
735 tw_compat_info = (TW_Compatibility_Info *)tw_ioctl->data_buffer;
736 memcpy(tw_compat_info, &tw_dev->tw_compat_info, sizeof(TW_Compatibility_Info));
737 break;
738 case TW_IOCTL_GET_LAST_EVENT:
739 if (tw_dev->event_queue_wrapped) {
740 if (tw_dev->aen_clobber) {
741 tw_ioctl->driver_command.status = TW_IOCTL_ERROR_STATUS_AEN_CLOBBER;
742 tw_dev->aen_clobber = 0;
743 } else
744 tw_ioctl->driver_command.status = 0;
745 } else {
746 if (!tw_dev->error_index) {
747 tw_ioctl->driver_command.status = TW_IOCTL_ERROR_STATUS_NO_MORE_EVENTS;
748 break;
749 }
750 tw_ioctl->driver_command.status = 0;
751 }
752 event_index = (tw_dev->error_index - 1 + TW_Q_LENGTH) % TW_Q_LENGTH;
753 memcpy(tw_ioctl->data_buffer, tw_dev->event_queue[event_index], sizeof(TW_Event));
754 tw_dev->event_queue[event_index]->retrieved = TW_AEN_RETRIEVED;
755 break;
756 case TW_IOCTL_GET_FIRST_EVENT:
757 if (tw_dev->event_queue_wrapped) {
758 if (tw_dev->aen_clobber) {
759 tw_ioctl->driver_command.status = TW_IOCTL_ERROR_STATUS_AEN_CLOBBER;
760 tw_dev->aen_clobber = 0;
761 } else
762 tw_ioctl->driver_command.status = 0;
763 event_index = tw_dev->error_index;
764 } else {
765 if (!tw_dev->error_index) {
766 tw_ioctl->driver_command.status = TW_IOCTL_ERROR_STATUS_NO_MORE_EVENTS;
767 break;
768 }
769 tw_ioctl->driver_command.status = 0;
770 event_index = 0;
771 }
772 memcpy(tw_ioctl->data_buffer, tw_dev->event_queue[event_index], sizeof(TW_Event));
773 tw_dev->event_queue[event_index]->retrieved = TW_AEN_RETRIEVED;
774 break;
775 case TW_IOCTL_GET_NEXT_EVENT:
776 event = (TW_Event *)tw_ioctl->data_buffer;
777 sequence_id = event->sequence_id;
778 tw_ioctl->driver_command.status = 0;
779
780 if (tw_dev->event_queue_wrapped) {
781 if (tw_dev->aen_clobber) {
782 tw_ioctl->driver_command.status = TW_IOCTL_ERROR_STATUS_AEN_CLOBBER;
783 tw_dev->aen_clobber = 0;
784 }
785 start_index = tw_dev->error_index;
786 } else {
787 if (!tw_dev->error_index) {
788 tw_ioctl->driver_command.status = TW_IOCTL_ERROR_STATUS_NO_MORE_EVENTS;
789 break;
790 }
791 start_index = 0;
792 }
793 event_index = (start_index + sequence_id - tw_dev->event_queue[start_index]->sequence_id + 1) % TW_Q_LENGTH;
794
795 if (!(tw_dev->event_queue[event_index]->sequence_id > sequence_id)) {
796 if (tw_ioctl->driver_command.status == TW_IOCTL_ERROR_STATUS_AEN_CLOBBER)
797 tw_dev->aen_clobber = 1;
798 tw_ioctl->driver_command.status = TW_IOCTL_ERROR_STATUS_NO_MORE_EVENTS;
799 break;
800 }
801 memcpy(tw_ioctl->data_buffer, tw_dev->event_queue[event_index], sizeof(TW_Event));
802 tw_dev->event_queue[event_index]->retrieved = TW_AEN_RETRIEVED;
803 break;
804 case TW_IOCTL_GET_PREVIOUS_EVENT:
805 event = (TW_Event *)tw_ioctl->data_buffer;
806 sequence_id = event->sequence_id;
807 tw_ioctl->driver_command.status = 0;
808
809 if (tw_dev->event_queue_wrapped) {
810 if (tw_dev->aen_clobber) {
811 tw_ioctl->driver_command.status = TW_IOCTL_ERROR_STATUS_AEN_CLOBBER;
812 tw_dev->aen_clobber = 0;
813 }
814 start_index = tw_dev->error_index;
815 } else {
816 if (!tw_dev->error_index) {
817 tw_ioctl->driver_command.status = TW_IOCTL_ERROR_STATUS_NO_MORE_EVENTS;
818 break;
819 }
820 start_index = 0;
821 }
822 event_index = (start_index + sequence_id - tw_dev->event_queue[start_index]->sequence_id - 1) % TW_Q_LENGTH;
823
824 if (!(tw_dev->event_queue[event_index]->sequence_id < sequence_id)) {
825 if (tw_ioctl->driver_command.status == TW_IOCTL_ERROR_STATUS_AEN_CLOBBER)
826 tw_dev->aen_clobber = 1;
827 tw_ioctl->driver_command.status = TW_IOCTL_ERROR_STATUS_NO_MORE_EVENTS;
828 break;
829 }
830 memcpy(tw_ioctl->data_buffer, tw_dev->event_queue[event_index], sizeof(TW_Event));
831 tw_dev->event_queue[event_index]->retrieved = TW_AEN_RETRIEVED;
832 break;
833 case TW_IOCTL_GET_LOCK:
834 tw_lock = (TW_Lock *)tw_ioctl->data_buffer;
835 do_gettimeofday(¤t_time);
836 current_time_ms = (current_time.tv_sec * 1000) + (current_time.tv_usec / 1000);
837
838 if ((tw_lock->force_flag == 1) || (tw_dev->ioctl_sem_lock == 0) || (current_time_ms >= tw_dev->ioctl_msec)) {
839 tw_dev->ioctl_sem_lock = 1;
840 tw_dev->ioctl_msec = current_time_ms + tw_lock->timeout_msec;
841 tw_ioctl->driver_command.status = 0;
842 tw_lock->time_remaining_msec = tw_lock->timeout_msec;
843 } else {
844 tw_ioctl->driver_command.status = TW_IOCTL_ERROR_STATUS_LOCKED;
845 tw_lock->time_remaining_msec = tw_dev->ioctl_msec - current_time_ms;
846 }
847 break;
848 case TW_IOCTL_RELEASE_LOCK:
849 if (tw_dev->ioctl_sem_lock == 1) {
850 tw_dev->ioctl_sem_lock = 0;
851 tw_ioctl->driver_command.status = 0;
852 } else {
853 tw_ioctl->driver_command.status = TW_IOCTL_ERROR_STATUS_NOT_LOCKED;
854 }
855 break;
856 default:
857 retval = TW_IOCTL_ERROR_OS_ENOTTY;
858 goto out3;
859 }
860
861
862 if (copy_to_user(argp, tw_ioctl, sizeof(TW_Ioctl_Buf_Apache) + driver_command.buffer_length - 1) == 0)
863 retval = 0;
864out3:
865
866 dma_free_coherent(&tw_dev->tw_pci_dev->dev, data_buffer_length_adjusted+sizeof(TW_Ioctl_Buf_Apache) - 1, cpu_addr, dma_handle);
867out2:
868 mutex_unlock(&tw_dev->ioctl_lock);
869out:
870 return retval;
871}
872
873
874
875static int twa_chrdev_open(struct inode *inode, struct file *file)
876{
877 unsigned int minor_number;
878 int retval = TW_IOCTL_ERROR_OS_ENODEV;
879
880 cycle_kernel_lock();
881 minor_number = iminor(inode);
882 if (minor_number >= twa_device_extension_count)
883 goto out;
884 retval = 0;
885out:
886 return retval;
887}
888
889
890static int twa_decode_bits(TW_Device_Extension *tw_dev, u32 status_reg_value)
891{
892 int retval = 1;
893
894
895 if (status_reg_value & TW_STATUS_PCI_PARITY_ERROR) {
896 TW_PRINTK(tw_dev->host, TW_DRIVER, 0xc, "PCI Parity Error: clearing");
897 writel(TW_CONTROL_CLEAR_PARITY_ERROR, TW_CONTROL_REG_ADDR(tw_dev));
898 }
899
900 if (status_reg_value & TW_STATUS_PCI_ABORT) {
901 TW_PRINTK(tw_dev->host, TW_DRIVER, 0xd, "PCI Abort: clearing");
902 writel(TW_CONTROL_CLEAR_PCI_ABORT, TW_CONTROL_REG_ADDR(tw_dev));
903 pci_write_config_word(tw_dev->tw_pci_dev, PCI_STATUS, TW_PCI_CLEAR_PCI_ABORT);
904 }
905
906 if (status_reg_value & TW_STATUS_QUEUE_ERROR) {
907 if (((tw_dev->tw_pci_dev->device != PCI_DEVICE_ID_3WARE_9650SE) &&
908 (tw_dev->tw_pci_dev->device != PCI_DEVICE_ID_3WARE_9690SA)) ||
909 (!test_bit(TW_IN_RESET, &tw_dev->flags)))
910 TW_PRINTK(tw_dev->host, TW_DRIVER, 0xe, "Controller Queue Error: clearing");
911 writel(TW_CONTROL_CLEAR_QUEUE_ERROR, TW_CONTROL_REG_ADDR(tw_dev));
912 }
913
914 if (status_reg_value & TW_STATUS_MICROCONTROLLER_ERROR) {
915 if (tw_dev->reset_print == 0) {
916 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x10, "Microcontroller Error: clearing");
917 tw_dev->reset_print = 1;
918 }
919 goto out;
920 }
921 retval = 0;
922out:
923 return retval;
924}
925
926
927static int twa_empty_response_queue(TW_Device_Extension *tw_dev)
928{
929 u32 status_reg_value, response_que_value;
930 int count = 0, retval = 1;
931
932 status_reg_value = readl(TW_STATUS_REG_ADDR(tw_dev));
933
934 while (((status_reg_value & TW_STATUS_RESPONSE_QUEUE_EMPTY) == 0) && (count < TW_MAX_RESPONSE_DRAIN)) {
935 response_que_value = readl(TW_RESPONSE_QUEUE_REG_ADDR(tw_dev));
936 status_reg_value = readl(TW_STATUS_REG_ADDR(tw_dev));
937 count++;
938 }
939 if (count == TW_MAX_RESPONSE_DRAIN)
940 goto out;
941
942 retval = 0;
943out:
944 return retval;
945}
946
947
948static int twa_empty_response_queue_large(TW_Device_Extension *tw_dev)
949{
950 u32 response_que_value = 0;
951 unsigned long before;
952 int retval = 1;
953
954 if (tw_dev->tw_pci_dev->device != PCI_DEVICE_ID_3WARE_9000) {
955 before = jiffies;
956 while ((response_que_value & TW_9550SX_DRAIN_COMPLETED) != TW_9550SX_DRAIN_COMPLETED) {
957 response_que_value = readl(TW_RESPONSE_QUEUE_REG_ADDR_LARGE(tw_dev));
958 msleep(1);
959 if (time_after(jiffies, before + HZ * 30))
960 goto out;
961 }
962
963 msleep(500);
964 retval = 0;
965 } else
966 retval = 0;
967out:
968 return retval;
969}
970
971
972static int twa_fill_sense(TW_Device_Extension *tw_dev, int request_id, int copy_sense, int print_host)
973{
974 TW_Command_Full *full_command_packet;
975 unsigned short error;
976 int retval = 1;
977 char *error_str;
978
979 full_command_packet = tw_dev->command_packet_virt[request_id];
980
981
982 error_str = &(full_command_packet->header.err_specific_desc[strlen(full_command_packet->header.err_specific_desc) + 1]);
983
984
985 error = le16_to_cpu(full_command_packet->header.status_block.error);
986 if ((error != TW_ERROR_LOGICAL_UNIT_NOT_SUPPORTED) && (error != TW_ERROR_UNIT_OFFLINE)) {
987 if (print_host)
988 printk(KERN_WARNING "3w-9xxx: scsi%d: ERROR: (0x%02X:0x%04X): %s:%s.\n",
989 tw_dev->host->host_no,
990 TW_MESSAGE_SOURCE_CONTROLLER_ERROR,
991 full_command_packet->header.status_block.error,
992 error_str[0] == '\0' ?
993 twa_string_lookup(twa_error_table,
994 full_command_packet->header.status_block.error) : error_str,
995 full_command_packet->header.err_specific_desc);
996 else
997 printk(KERN_WARNING "3w-9xxx: ERROR: (0x%02X:0x%04X): %s:%s.\n",
998 TW_MESSAGE_SOURCE_CONTROLLER_ERROR,
999 full_command_packet->header.status_block.error,
1000 error_str[0] == '\0' ?
1001 twa_string_lookup(twa_error_table,
1002 full_command_packet->header.status_block.error) : error_str,
1003 full_command_packet->header.err_specific_desc);
1004 }
1005
1006 if (copy_sense) {
1007 memcpy(tw_dev->srb[request_id]->sense_buffer, full_command_packet->header.sense_data, TW_SENSE_DATA_LENGTH);
1008 tw_dev->srb[request_id]->result = (full_command_packet->command.newcommand.status << 1);
1009 retval = TW_ISR_DONT_RESULT;
1010 goto out;
1011 }
1012 retval = 0;
1013out:
1014 return retval;
1015}
1016
1017
1018static void twa_free_device_extension(TW_Device_Extension *tw_dev)
1019{
1020 if (tw_dev->command_packet_virt[0])
1021 pci_free_consistent(tw_dev->tw_pci_dev,
1022 sizeof(TW_Command_Full)*TW_Q_LENGTH,
1023 tw_dev->command_packet_virt[0],
1024 tw_dev->command_packet_phys[0]);
1025
1026 if (tw_dev->generic_buffer_virt[0])
1027 pci_free_consistent(tw_dev->tw_pci_dev,
1028 TW_SECTOR_SIZE*TW_Q_LENGTH,
1029 tw_dev->generic_buffer_virt[0],
1030 tw_dev->generic_buffer_phys[0]);
1031
1032 kfree(tw_dev->event_queue[0]);
1033}
1034
1035
1036static void twa_free_request_id(TW_Device_Extension *tw_dev, int request_id)
1037{
1038 tw_dev->free_queue[tw_dev->free_tail] = request_id;
1039 tw_dev->state[request_id] = TW_S_FINISHED;
1040 tw_dev->free_tail = (tw_dev->free_tail + 1) % TW_Q_LENGTH;
1041}
1042
1043
1044static void *twa_get_param(TW_Device_Extension *tw_dev, int request_id, int table_id, int parameter_id, int parameter_size_bytes)
1045{
1046 TW_Command_Full *full_command_packet;
1047 TW_Command *command_packet;
1048 TW_Param_Apache *param;
1049 void *retval = NULL;
1050
1051
1052 full_command_packet = tw_dev->command_packet_virt[request_id];
1053 memset(full_command_packet, 0, sizeof(TW_Command_Full));
1054 command_packet = &full_command_packet->command.oldcommand;
1055
1056 command_packet->opcode__sgloffset = TW_OPSGL_IN(2, TW_OP_GET_PARAM);
1057 command_packet->size = TW_COMMAND_SIZE;
1058 command_packet->request_id = request_id;
1059 command_packet->byte6_offset.block_count = cpu_to_le16(1);
1060
1061
1062 param = (TW_Param_Apache *)tw_dev->generic_buffer_virt[request_id];
1063 memset(param, 0, TW_SECTOR_SIZE);
1064 param->table_id = cpu_to_le16(table_id | 0x8000);
1065 param->parameter_id = cpu_to_le16(parameter_id);
1066 param->parameter_size_bytes = cpu_to_le16(parameter_size_bytes);
1067
1068 command_packet->byte8_offset.param.sgl[0].address = TW_CPU_TO_SGL(tw_dev->generic_buffer_phys[request_id]);
1069 command_packet->byte8_offset.param.sgl[0].length = cpu_to_le32(TW_SECTOR_SIZE);
1070
1071
1072 twa_post_command_packet(tw_dev, request_id, 1);
1073
1074
1075 if (twa_poll_response(tw_dev, request_id, 30))
1076 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x13, "No valid response during get param")
1077 else
1078 retval = (void *)&(param->data[0]);
1079
1080 tw_dev->posted_request_count--;
1081 tw_dev->state[request_id] = TW_S_INITIAL;
1082
1083 return retval;
1084}
1085
1086
1087static void twa_get_request_id(TW_Device_Extension *tw_dev, int *request_id)
1088{
1089 *request_id = tw_dev->free_queue[tw_dev->free_head];
1090 tw_dev->free_head = (tw_dev->free_head + 1) % TW_Q_LENGTH;
1091 tw_dev->state[*request_id] = TW_S_STARTED;
1092}
1093
1094
1095static int twa_initconnection(TW_Device_Extension *tw_dev, int message_credits,
1096 u32 set_features, unsigned short current_fw_srl,
1097 unsigned short current_fw_arch_id,
1098 unsigned short current_fw_branch,
1099 unsigned short current_fw_build,
1100 unsigned short *fw_on_ctlr_srl,
1101 unsigned short *fw_on_ctlr_arch_id,
1102 unsigned short *fw_on_ctlr_branch,
1103 unsigned short *fw_on_ctlr_build,
1104 u32 *init_connect_result)
1105{
1106 TW_Command_Full *full_command_packet;
1107 TW_Initconnect *tw_initconnect;
1108 int request_id = 0, retval = 1;
1109
1110
1111 full_command_packet = tw_dev->command_packet_virt[request_id];
1112 memset(full_command_packet, 0, sizeof(TW_Command_Full));
1113 full_command_packet->header.header_desc.size_header = 128;
1114
1115 tw_initconnect = (TW_Initconnect *)&full_command_packet->command.oldcommand;
1116 tw_initconnect->opcode__reserved = TW_OPRES_IN(0, TW_OP_INIT_CONNECTION);
1117 tw_initconnect->request_id = request_id;
1118 tw_initconnect->message_credits = cpu_to_le16(message_credits);
1119 tw_initconnect->features = set_features;
1120
1121
1122 tw_initconnect->features |= sizeof(dma_addr_t) > 4 ? 1 : 0;
1123
1124 tw_initconnect->features = cpu_to_le32(tw_initconnect->features);
1125
1126 if (set_features & TW_EXTENDED_INIT_CONNECT) {
1127 tw_initconnect->size = TW_INIT_COMMAND_PACKET_SIZE_EXTENDED;
1128 tw_initconnect->fw_srl = cpu_to_le16(current_fw_srl);
1129 tw_initconnect->fw_arch_id = cpu_to_le16(current_fw_arch_id);
1130 tw_initconnect->fw_branch = cpu_to_le16(current_fw_branch);
1131 tw_initconnect->fw_build = cpu_to_le16(current_fw_build);
1132 } else
1133 tw_initconnect->size = TW_INIT_COMMAND_PACKET_SIZE;
1134
1135
1136 twa_post_command_packet(tw_dev, request_id, 1);
1137
1138
1139 if (twa_poll_response(tw_dev, request_id, 30)) {
1140 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x15, "No valid response during init connection");
1141 } else {
1142 if (set_features & TW_EXTENDED_INIT_CONNECT) {
1143 *fw_on_ctlr_srl = le16_to_cpu(tw_initconnect->fw_srl);
1144 *fw_on_ctlr_arch_id = le16_to_cpu(tw_initconnect->fw_arch_id);
1145 *fw_on_ctlr_branch = le16_to_cpu(tw_initconnect->fw_branch);
1146 *fw_on_ctlr_build = le16_to_cpu(tw_initconnect->fw_build);
1147 *init_connect_result = le32_to_cpu(tw_initconnect->result);
1148 }
1149 retval = 0;
1150 }
1151
1152 tw_dev->posted_request_count--;
1153 tw_dev->state[request_id] = TW_S_INITIAL;
1154
1155 return retval;
1156}
1157
1158
1159static int twa_initialize_device_extension(TW_Device_Extension *tw_dev)
1160{
1161 int i, retval = 1;
1162
1163
1164 if (twa_allocate_memory(tw_dev, sizeof(TW_Command_Full), 0)) {
1165 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x16, "Command packet memory allocation failed");
1166 goto out;
1167 }
1168
1169
1170 if (twa_allocate_memory(tw_dev, TW_SECTOR_SIZE, 1)) {
1171 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x17, "Generic memory allocation failed");
1172 goto out;
1173 }
1174
1175
1176 tw_dev->event_queue[0] = kcalloc(TW_Q_LENGTH, sizeof(TW_Event), GFP_KERNEL);
1177 if (!tw_dev->event_queue[0]) {
1178 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x18, "Event info memory allocation failed");
1179 goto out;
1180 }
1181
1182
1183 for (i = 0; i < TW_Q_LENGTH; i++) {
1184 tw_dev->event_queue[i] = (TW_Event *)((unsigned char *)tw_dev->event_queue[0] + (i * sizeof(TW_Event)));
1185 tw_dev->free_queue[i] = i;
1186 tw_dev->state[i] = TW_S_INITIAL;
1187 }
1188
1189 tw_dev->pending_head = TW_Q_START;
1190 tw_dev->pending_tail = TW_Q_START;
1191 tw_dev->free_head = TW_Q_START;
1192 tw_dev->free_tail = TW_Q_START;
1193 tw_dev->error_sequence_id = 1;
1194 tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE;
1195
1196 mutex_init(&tw_dev->ioctl_lock);
1197 init_waitqueue_head(&tw_dev->ioctl_wqueue);
1198
1199 retval = 0;
1200out:
1201 return retval;
1202}
1203
1204
1205static irqreturn_t twa_interrupt(int irq, void *dev_instance)
1206{
1207 int request_id, error = 0;
1208 u32 status_reg_value;
1209 TW_Response_Queue response_que;
1210 TW_Command_Full *full_command_packet;
1211 TW_Device_Extension *tw_dev = (TW_Device_Extension *)dev_instance;
1212 int handled = 0;
1213
1214
1215 spin_lock(tw_dev->host->host_lock);
1216
1217
1218 status_reg_value = readl(TW_STATUS_REG_ADDR(tw_dev));
1219
1220
1221 if (!(status_reg_value & TW_STATUS_VALID_INTERRUPT))
1222 goto twa_interrupt_bail;
1223
1224 handled = 1;
1225
1226
1227 if (test_bit(TW_IN_RESET, &tw_dev->flags))
1228 goto twa_interrupt_bail;
1229
1230
1231 if (twa_check_bits(status_reg_value)) {
1232 if (twa_decode_bits(tw_dev, status_reg_value)) {
1233 TW_CLEAR_ALL_INTERRUPTS(tw_dev);
1234 goto twa_interrupt_bail;
1235 }
1236 }
1237
1238
1239 if (status_reg_value & TW_STATUS_HOST_INTERRUPT)
1240 TW_CLEAR_HOST_INTERRUPT(tw_dev);
1241
1242
1243 if (status_reg_value & TW_STATUS_ATTENTION_INTERRUPT) {
1244 TW_CLEAR_ATTENTION_INTERRUPT(tw_dev);
1245 if (!(test_and_set_bit(TW_IN_ATTENTION_LOOP, &tw_dev->flags))) {
1246 twa_get_request_id(tw_dev, &request_id);
1247
1248 error = twa_aen_read_queue(tw_dev, request_id);
1249 if (error) {
1250 tw_dev->state[request_id] = TW_S_COMPLETED;
1251 twa_free_request_id(tw_dev, request_id);
1252 clear_bit(TW_IN_ATTENTION_LOOP, &tw_dev->flags);
1253 }
1254 }
1255 }
1256
1257
1258 if (status_reg_value & TW_STATUS_COMMAND_INTERRUPT) {
1259 TW_MASK_COMMAND_INTERRUPT(tw_dev);
1260
1261 while (tw_dev->pending_request_count > 0) {
1262 request_id = tw_dev->pending_queue[tw_dev->pending_head];
1263 if (tw_dev->state[request_id] != TW_S_PENDING) {
1264 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x19, "Found request id that wasn't pending");
1265 TW_CLEAR_ALL_INTERRUPTS(tw_dev);
1266 goto twa_interrupt_bail;
1267 }
1268 if (twa_post_command_packet(tw_dev, request_id, 1)==0) {
1269 tw_dev->pending_head = (tw_dev->pending_head + 1) % TW_Q_LENGTH;
1270 tw_dev->pending_request_count--;
1271 } else {
1272
1273 break;
1274 }
1275 }
1276 }
1277
1278
1279 if (status_reg_value & TW_STATUS_RESPONSE_INTERRUPT) {
1280
1281
1282 while ((status_reg_value & TW_STATUS_RESPONSE_QUEUE_EMPTY) == 0) {
1283
1284 response_que.value = readl(TW_RESPONSE_QUEUE_REG_ADDR(tw_dev));
1285 request_id = TW_RESID_OUT(response_que.response_id);
1286 full_command_packet = tw_dev->command_packet_virt[request_id];
1287 error = 0;
1288
1289 if (full_command_packet->command.newcommand.status != 0) {
1290 if (tw_dev->srb[request_id] != NULL) {
1291 error = twa_fill_sense(tw_dev, request_id, 1, 1);
1292 } else {
1293
1294 if (request_id != tw_dev->chrdev_request_id) {
1295 error = twa_fill_sense(tw_dev, request_id, 0, 1);
1296 }
1297 }
1298 }
1299
1300
1301 if (tw_dev->state[request_id] != TW_S_POSTED) {
1302 if (tw_dev->srb[request_id] != NULL) {
1303 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1a, "Received a request id that wasn't posted");
1304 TW_CLEAR_ALL_INTERRUPTS(tw_dev);
1305 goto twa_interrupt_bail;
1306 }
1307 }
1308
1309
1310 if (tw_dev->srb[request_id] == NULL) {
1311 if (request_id != tw_dev->chrdev_request_id) {
1312 if (twa_aen_complete(tw_dev, request_id))
1313 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1b, "Error completing AEN during attention interrupt");
1314 } else {
1315 tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE;
1316 wake_up(&tw_dev->ioctl_wqueue);
1317 }
1318 } else {
1319 struct scsi_cmnd *cmd;
1320
1321 cmd = tw_dev->srb[request_id];
1322
1323 twa_scsiop_execute_scsi_complete(tw_dev, request_id);
1324
1325 if (error == 0) {
1326 cmd->result = (DID_OK << 16);
1327 }
1328
1329
1330 if (error == 1) {
1331
1332 cmd->result = (DID_OK << 16) | (CHECK_CONDITION << 1);
1333 }
1334
1335
1336 if ((scsi_sg_count(cmd) <= 1) && (full_command_packet->command.newcommand.status == 0)) {
1337 if (full_command_packet->command.newcommand.sg_list[0].length < scsi_bufflen(tw_dev->srb[request_id]))
1338 scsi_set_resid(cmd, scsi_bufflen(cmd) - full_command_packet->command.newcommand.sg_list[0].length);
1339 }
1340
1341
1342 tw_dev->state[request_id] = TW_S_COMPLETED;
1343 twa_free_request_id(tw_dev, request_id);
1344 tw_dev->posted_request_count--;
1345 tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
1346 twa_unmap_scsi_data(tw_dev, request_id);
1347 }
1348
1349
1350 status_reg_value = readl(TW_STATUS_REG_ADDR(tw_dev));
1351 if (twa_check_bits(status_reg_value)) {
1352 if (twa_decode_bits(tw_dev, status_reg_value)) {
1353 TW_CLEAR_ALL_INTERRUPTS(tw_dev);
1354 goto twa_interrupt_bail;
1355 }
1356 }
1357 }
1358 }
1359
1360twa_interrupt_bail:
1361 spin_unlock(tw_dev->host->host_lock);
1362 return IRQ_RETVAL(handled);
1363}
1364
1365
1366static void twa_load_sgl(TW_Device_Extension *tw_dev, TW_Command_Full *full_command_packet, int request_id, dma_addr_t dma_handle, int length)
1367{
1368 TW_Command *oldcommand;
1369 TW_Command_Apache *newcommand;
1370 TW_SG_Entry *sgl;
1371 unsigned int pae = 0;
1372
1373 if ((sizeof(long) < 8) && (sizeof(dma_addr_t) > 4))
1374 pae = 1;
1375
1376 if (TW_OP_OUT(full_command_packet->command.newcommand.opcode__reserved) == TW_OP_EXECUTE_SCSI) {
1377 newcommand = &full_command_packet->command.newcommand;
1378 newcommand->request_id__lunl =
1379 cpu_to_le16(TW_REQ_LUN_IN(TW_LUN_OUT(newcommand->request_id__lunl), request_id));
1380 newcommand->sg_list[0].address = TW_CPU_TO_SGL(dma_handle + sizeof(TW_Ioctl_Buf_Apache) - 1);
1381 newcommand->sg_list[0].length = cpu_to_le32(length);
1382 newcommand->sgl_entries__lunh =
1383 cpu_to_le16(TW_REQ_LUN_IN(TW_LUN_OUT(newcommand->sgl_entries__lunh), 1));
1384 } else {
1385 oldcommand = &full_command_packet->command.oldcommand;
1386 oldcommand->request_id = request_id;
1387
1388 if (TW_SGL_OUT(oldcommand->opcode__sgloffset)) {
1389
1390 if (tw_dev->tw_pci_dev->device == PCI_DEVICE_ID_3WARE_9690SA)
1391 sgl = (TW_SG_Entry *)((u32 *)oldcommand+oldcommand->size - (sizeof(TW_SG_Entry)/4) + pae);
1392 else
1393 sgl = (TW_SG_Entry *)((u32 *)oldcommand+TW_SGL_OUT(oldcommand->opcode__sgloffset));
1394 sgl->address = TW_CPU_TO_SGL(dma_handle + sizeof(TW_Ioctl_Buf_Apache) - 1);
1395 sgl->length = cpu_to_le32(length);
1396
1397 oldcommand->size += pae;
1398 }
1399 }
1400}
1401
1402
1403static int twa_map_scsi_sg_data(TW_Device_Extension *tw_dev, int request_id)
1404{
1405 int use_sg;
1406 struct scsi_cmnd *cmd = tw_dev->srb[request_id];
1407
1408 use_sg = scsi_dma_map(cmd);
1409 if (!use_sg)
1410 return 0;
1411 else if (use_sg < 0) {
1412 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1c, "Failed to map scatter gather list");
1413 return 0;
1414 }
1415
1416 cmd->SCp.phase = TW_PHASE_SGLIST;
1417 cmd->SCp.have_data_in = use_sg;
1418
1419 return use_sg;
1420}
1421
1422
1423static int twa_poll_response(TW_Device_Extension *tw_dev, int request_id, int seconds)
1424{
1425 int retval = 1, found = 0, response_request_id;
1426 TW_Response_Queue response_queue;
1427 TW_Command_Full *full_command_packet = tw_dev->command_packet_virt[request_id];
1428
1429 if (twa_poll_status_gone(tw_dev, TW_STATUS_RESPONSE_QUEUE_EMPTY, seconds) == 0) {
1430 response_queue.value = readl(TW_RESPONSE_QUEUE_REG_ADDR(tw_dev));
1431 response_request_id = TW_RESID_OUT(response_queue.response_id);
1432 if (request_id != response_request_id) {
1433 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1e, "Found unexpected request id while polling for response");
1434 goto out;
1435 }
1436 if (TW_OP_OUT(full_command_packet->command.newcommand.opcode__reserved) == TW_OP_EXECUTE_SCSI) {
1437 if (full_command_packet->command.newcommand.status != 0) {
1438
1439 twa_fill_sense(tw_dev, request_id, 0, 0);
1440 goto out;
1441 }
1442 found = 1;
1443 } else {
1444 if (full_command_packet->command.oldcommand.status != 0) {
1445
1446 twa_fill_sense(tw_dev, request_id, 0, 0);
1447 goto out;
1448 }
1449 found = 1;
1450 }
1451 }
1452
1453 if (found)
1454 retval = 0;
1455out:
1456 return retval;
1457}
1458
1459
1460static int twa_poll_status(TW_Device_Extension *tw_dev, u32 flag, int seconds)
1461{
1462 u32 status_reg_value;
1463 unsigned long before;
1464 int retval = 1;
1465
1466 status_reg_value = readl(TW_STATUS_REG_ADDR(tw_dev));
1467 before = jiffies;
1468
1469 if (twa_check_bits(status_reg_value))
1470 twa_decode_bits(tw_dev, status_reg_value);
1471
1472 while ((status_reg_value & flag) != flag) {
1473 status_reg_value = readl(TW_STATUS_REG_ADDR(tw_dev));
1474
1475 if (twa_check_bits(status_reg_value))
1476 twa_decode_bits(tw_dev, status_reg_value);
1477
1478 if (time_after(jiffies, before + HZ * seconds))
1479 goto out;
1480
1481 msleep(50);
1482 }
1483 retval = 0;
1484out:
1485 return retval;
1486}
1487
1488
1489static int twa_poll_status_gone(TW_Device_Extension *tw_dev, u32 flag, int seconds)
1490{
1491 u32 status_reg_value;
1492 unsigned long before;
1493 int retval = 1;
1494
1495 status_reg_value = readl(TW_STATUS_REG_ADDR(tw_dev));
1496 before = jiffies;
1497
1498 if (twa_check_bits(status_reg_value))
1499 twa_decode_bits(tw_dev, status_reg_value);
1500
1501 while ((status_reg_value & flag) != 0) {
1502 status_reg_value = readl(TW_STATUS_REG_ADDR(tw_dev));
1503 if (twa_check_bits(status_reg_value))
1504 twa_decode_bits(tw_dev, status_reg_value);
1505
1506 if (time_after(jiffies, before + HZ * seconds))
1507 goto out;
1508
1509 msleep(50);
1510 }
1511 retval = 0;
1512out:
1513 return retval;
1514}
1515
1516
1517static int twa_post_command_packet(TW_Device_Extension *tw_dev, int request_id, char internal)
1518{
1519 u32 status_reg_value;
1520 dma_addr_t command_que_value;
1521 int retval = 1;
1522
1523 command_que_value = tw_dev->command_packet_phys[request_id];
1524
1525
1526 if ((tw_dev->tw_pci_dev->device == PCI_DEVICE_ID_3WARE_9650SE) ||
1527 (tw_dev->tw_pci_dev->device == PCI_DEVICE_ID_3WARE_9690SA)) {
1528 command_que_value += TW_COMMAND_OFFSET;
1529 writel((u32)command_que_value, TW_COMMAND_QUEUE_REG_ADDR_LARGE(tw_dev));
1530 }
1531
1532 status_reg_value = readl(TW_STATUS_REG_ADDR(tw_dev));
1533
1534 if (twa_check_bits(status_reg_value))
1535 twa_decode_bits(tw_dev, status_reg_value);
1536
1537 if (((tw_dev->pending_request_count > 0) && (tw_dev->state[request_id] != TW_S_PENDING)) || (status_reg_value & TW_STATUS_COMMAND_QUEUE_FULL)) {
1538
1539
1540 if (!internal) {
1541 retval = SCSI_MLQUEUE_HOST_BUSY;
1542 goto out;
1543 }
1544
1545
1546 if (tw_dev->state[request_id] != TW_S_PENDING) {
1547 tw_dev->state[request_id] = TW_S_PENDING;
1548 tw_dev->pending_request_count++;
1549 if (tw_dev->pending_request_count > tw_dev->max_pending_request_count) {
1550 tw_dev->max_pending_request_count = tw_dev->pending_request_count;
1551 }
1552 tw_dev->pending_queue[tw_dev->pending_tail] = request_id;
1553 tw_dev->pending_tail = (tw_dev->pending_tail + 1) % TW_Q_LENGTH;
1554 }
1555 TW_UNMASK_COMMAND_INTERRUPT(tw_dev);
1556 goto out;
1557 } else {
1558 if ((tw_dev->tw_pci_dev->device == PCI_DEVICE_ID_3WARE_9650SE) ||
1559 (tw_dev->tw_pci_dev->device == PCI_DEVICE_ID_3WARE_9690SA)) {
1560
1561 writel((u32)((u64)command_que_value >> 32), TW_COMMAND_QUEUE_REG_ADDR_LARGE(tw_dev) + 0x4);
1562 } else {
1563 if (sizeof(dma_addr_t) > 4) {
1564 command_que_value += TW_COMMAND_OFFSET;
1565 writel((u32)command_que_value, TW_COMMAND_QUEUE_REG_ADDR(tw_dev));
1566 writel((u32)((u64)command_que_value >> 32), TW_COMMAND_QUEUE_REG_ADDR(tw_dev) + 0x4);
1567 } else {
1568 writel(TW_COMMAND_OFFSET + command_que_value, TW_COMMAND_QUEUE_REG_ADDR(tw_dev));
1569 }
1570 }
1571 tw_dev->state[request_id] = TW_S_POSTED;
1572 tw_dev->posted_request_count++;
1573 if (tw_dev->posted_request_count > tw_dev->max_posted_request_count) {
1574 tw_dev->max_posted_request_count = tw_dev->posted_request_count;
1575 }
1576 }
1577 retval = 0;
1578out:
1579 return retval;
1580}
1581
1582
1583static int twa_reset_device_extension(TW_Device_Extension *tw_dev)
1584{
1585 int i = 0;
1586 int retval = 1;
1587 unsigned long flags = 0;
1588
1589 set_bit(TW_IN_RESET, &tw_dev->flags);
1590 TW_DISABLE_INTERRUPTS(tw_dev);
1591 TW_MASK_COMMAND_INTERRUPT(tw_dev);
1592 spin_lock_irqsave(tw_dev->host->host_lock, flags);
1593
1594
1595 for (i = 0; i < TW_Q_LENGTH; i++) {
1596 if ((tw_dev->state[i] != TW_S_FINISHED) &&
1597 (tw_dev->state[i] != TW_S_INITIAL) &&
1598 (tw_dev->state[i] != TW_S_COMPLETED)) {
1599 if (tw_dev->srb[i]) {
1600 tw_dev->srb[i]->result = (DID_RESET << 16);
1601 tw_dev->srb[i]->scsi_done(tw_dev->srb[i]);
1602 twa_unmap_scsi_data(tw_dev, i);
1603 }
1604 }
1605 }
1606
1607
1608 for (i = 0; i < TW_Q_LENGTH; i++) {
1609 tw_dev->free_queue[i] = i;
1610 tw_dev->state[i] = TW_S_INITIAL;
1611 }
1612 tw_dev->free_head = TW_Q_START;
1613 tw_dev->free_tail = TW_Q_START;
1614 tw_dev->posted_request_count = 0;
1615 tw_dev->pending_request_count = 0;
1616 tw_dev->pending_head = TW_Q_START;
1617 tw_dev->pending_tail = TW_Q_START;
1618 tw_dev->reset_print = 0;
1619
1620 spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
1621
1622 if (twa_reset_sequence(tw_dev, 1))
1623 goto out;
1624
1625 TW_ENABLE_AND_CLEAR_INTERRUPTS(tw_dev);
1626 clear_bit(TW_IN_RESET, &tw_dev->flags);
1627 tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE;
1628
1629 retval = 0;
1630out:
1631 return retval;
1632}
1633
1634
1635static int twa_reset_sequence(TW_Device_Extension *tw_dev, int soft_reset)
1636{
1637 int tries = 0, retval = 1, flashed = 0, do_soft_reset = soft_reset;
1638
1639 while (tries < TW_MAX_RESET_TRIES) {
1640 if (do_soft_reset) {
1641 TW_SOFT_RESET(tw_dev);
1642
1643 if (twa_empty_response_queue_large(tw_dev)) {
1644 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x36, "Response queue (large) empty failed during reset sequence");
1645 do_soft_reset = 1;
1646 tries++;
1647 continue;
1648 }
1649 }
1650
1651
1652 if (twa_poll_status(tw_dev, TW_STATUS_MICROCONTROLLER_READY | (do_soft_reset == 1 ? TW_STATUS_ATTENTION_INTERRUPT : 0), 60)) {
1653 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1f, "Microcontroller not ready during reset sequence");
1654 do_soft_reset = 1;
1655 tries++;
1656 continue;
1657 }
1658
1659
1660 if (twa_empty_response_queue(tw_dev)) {
1661 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x20, "Response queue empty failed during reset sequence");
1662 do_soft_reset = 1;
1663 tries++;
1664 continue;
1665 }
1666
1667 flashed = 0;
1668
1669
1670 if (twa_check_srl(tw_dev, &flashed)) {
1671 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x21, "Compatibility check failed during reset sequence");
1672 do_soft_reset = 1;
1673 tries++;
1674 continue;
1675 } else {
1676 if (flashed) {
1677 tries++;
1678 continue;
1679 }
1680 }
1681
1682
1683 if (twa_aen_drain_queue(tw_dev, soft_reset)) {
1684 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x22, "AEN drain failed during reset sequence");
1685 do_soft_reset = 1;
1686 tries++;
1687 continue;
1688 }
1689
1690
1691 retval = 0;
1692 goto out;
1693 }
1694out:
1695 return retval;
1696}
1697
1698
1699static int twa_scsi_biosparam(struct scsi_device *sdev, struct block_device *bdev, sector_t capacity, int geom[])
1700{
1701 int heads, sectors, cylinders;
1702 TW_Device_Extension *tw_dev;
1703
1704 tw_dev = (TW_Device_Extension *)sdev->host->hostdata;
1705
1706 if (capacity >= 0x200000) {
1707 heads = 255;
1708 sectors = 63;
1709 cylinders = sector_div(capacity, heads * sectors);
1710 } else {
1711 heads = 64;
1712 sectors = 32;
1713 cylinders = sector_div(capacity, heads * sectors);
1714 }
1715
1716 geom[0] = heads;
1717 geom[1] = sectors;
1718 geom[2] = cylinders;
1719
1720 return 0;
1721}
1722
1723
1724static int twa_scsi_eh_reset(struct scsi_cmnd *SCpnt)
1725{
1726 TW_Device_Extension *tw_dev = NULL;
1727 int retval = FAILED;
1728
1729 tw_dev = (TW_Device_Extension *)SCpnt->device->host->hostdata;
1730
1731 tw_dev->num_resets++;
1732
1733 sdev_printk(KERN_WARNING, SCpnt->device,
1734 "WARNING: (0x%02X:0x%04X): Command (0x%x) timed out, resetting card.\n",
1735 TW_DRIVER, 0x2c, SCpnt->cmnd[0]);
1736
1737
1738 mutex_lock(&tw_dev->ioctl_lock);
1739
1740
1741 if (twa_reset_device_extension(tw_dev)) {
1742 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x2b, "Controller reset failed during scsi host reset");
1743 goto out;
1744 }
1745
1746 retval = SUCCESS;
1747out:
1748 mutex_unlock(&tw_dev->ioctl_lock);
1749 return retval;
1750}
1751
1752
1753static int twa_scsi_queue(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
1754{
1755 int request_id, retval;
1756 TW_Device_Extension *tw_dev = (TW_Device_Extension *)SCpnt->device->host->hostdata;
1757
1758
1759 if (test_bit(TW_IN_RESET, &tw_dev->flags)) {
1760 retval = SCSI_MLQUEUE_HOST_BUSY;
1761 goto out;
1762 }
1763
1764
1765 if ((SCpnt->device->lun != 0) && (tw_dev->tw_compat_info.working_srl < TW_FW_SRL_LUNS_SUPPORTED)) {
1766 SCpnt->result = (DID_BAD_TARGET << 16);
1767 done(SCpnt);
1768 retval = 0;
1769 goto out;
1770 }
1771
1772
1773 SCpnt->scsi_done = done;
1774
1775
1776 twa_get_request_id(tw_dev, &request_id);
1777
1778
1779 tw_dev->srb[request_id] = SCpnt;
1780
1781
1782 SCpnt->SCp.phase = TW_PHASE_INITIAL;
1783
1784 retval = twa_scsiop_execute_scsi(tw_dev, request_id, NULL, 0, NULL);
1785 switch (retval) {
1786 case SCSI_MLQUEUE_HOST_BUSY:
1787 twa_free_request_id(tw_dev, request_id);
1788 break;
1789 case 1:
1790 tw_dev->state[request_id] = TW_S_COMPLETED;
1791 twa_free_request_id(tw_dev, request_id);
1792 SCpnt->result = (DID_ERROR << 16);
1793 done(SCpnt);
1794 retval = 0;
1795 }
1796out:
1797 return retval;
1798}
1799
1800
1801static int twa_scsiop_execute_scsi(TW_Device_Extension *tw_dev, int request_id, char *cdb, int use_sg, TW_SG_Entry *sglistarg)
1802{
1803 TW_Command_Full *full_command_packet;
1804 TW_Command_Apache *command_packet;
1805 u32 num_sectors = 0x0;
1806 int i, sg_count;
1807 struct scsi_cmnd *srb = NULL;
1808 struct scatterlist *sglist = NULL, *sg;
1809 int retval = 1;
1810
1811 if (tw_dev->srb[request_id]) {
1812 srb = tw_dev->srb[request_id];
1813 if (scsi_sglist(srb))
1814 sglist = scsi_sglist(srb);
1815 }
1816
1817
1818 full_command_packet = tw_dev->command_packet_virt[request_id];
1819 full_command_packet->header.header_desc.size_header = 128;
1820 full_command_packet->header.status_block.error = 0;
1821 full_command_packet->header.status_block.severity__reserved = 0;
1822
1823 command_packet = &full_command_packet->command.newcommand;
1824 command_packet->status = 0;
1825 command_packet->opcode__reserved = TW_OPRES_IN(0, TW_OP_EXECUTE_SCSI);
1826
1827
1828 if (!cdb)
1829 memcpy(command_packet->cdb, srb->cmnd, TW_MAX_CDB_LEN);
1830 else
1831 memcpy(command_packet->cdb, cdb, TW_MAX_CDB_LEN);
1832
1833 if (srb) {
1834 command_packet->unit = srb->device->id;
1835 command_packet->request_id__lunl =
1836 cpu_to_le16(TW_REQ_LUN_IN(srb->device->lun, request_id));
1837 } else {
1838 command_packet->request_id__lunl =
1839 cpu_to_le16(TW_REQ_LUN_IN(0, request_id));
1840 command_packet->unit = 0;
1841 }
1842
1843 command_packet->sgl_offset = 16;
1844
1845 if (!sglistarg) {
1846
1847
1848 if (scsi_sg_count(srb)) {
1849 if ((scsi_sg_count(srb) == 1) &&
1850 (scsi_bufflen(srb) < TW_MIN_SGL_LENGTH)) {
1851 if (srb->sc_data_direction == DMA_TO_DEVICE ||
1852 srb->sc_data_direction == DMA_BIDIRECTIONAL)
1853 scsi_sg_copy_to_buffer(srb,
1854 tw_dev->generic_buffer_virt[request_id],
1855 TW_SECTOR_SIZE);
1856 command_packet->sg_list[0].address = TW_CPU_TO_SGL(tw_dev->generic_buffer_phys[request_id]);
1857 command_packet->sg_list[0].length = cpu_to_le32(TW_MIN_SGL_LENGTH);
1858 } else {
1859 sg_count = twa_map_scsi_sg_data(tw_dev, request_id);
1860 if (sg_count == 0)
1861 goto out;
1862
1863 scsi_for_each_sg(srb, sg, sg_count, i) {
1864 command_packet->sg_list[i].address = TW_CPU_TO_SGL(sg_dma_address(sg));
1865 command_packet->sg_list[i].length = cpu_to_le32(sg_dma_len(sg));
1866 if (command_packet->sg_list[i].address & TW_CPU_TO_SGL(TW_ALIGNMENT_9000_SGL)) {
1867 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x2e, "Found unaligned sgl address during execute scsi");
1868 goto out;
1869 }
1870 }
1871 }
1872 command_packet->sgl_entries__lunh = cpu_to_le16(TW_REQ_LUN_IN((srb->device->lun >> 4), scsi_sg_count(tw_dev->srb[request_id])));
1873 }
1874 } else {
1875
1876 for (i = 0; i < use_sg; i++) {
1877 command_packet->sg_list[i].address = TW_CPU_TO_SGL(sglistarg[i].address);
1878 command_packet->sg_list[i].length = cpu_to_le32(sglistarg[i].length);
1879 if (command_packet->sg_list[i].address & TW_CPU_TO_SGL(TW_ALIGNMENT_9000_SGL)) {
1880 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x2f, "Found unaligned sgl address during internal post");
1881 goto out;
1882 }
1883 }
1884 command_packet->sgl_entries__lunh = cpu_to_le16(TW_REQ_LUN_IN(0, use_sg));
1885 }
1886
1887 if (srb) {
1888 if (srb->cmnd[0] == READ_6 || srb->cmnd[0] == WRITE_6)
1889 num_sectors = (u32)srb->cmnd[4];
1890
1891 if (srb->cmnd[0] == READ_10 || srb->cmnd[0] == WRITE_10)
1892 num_sectors = (u32)srb->cmnd[8] | ((u32)srb->cmnd[7] << 8);
1893 }
1894
1895
1896 tw_dev->sector_count = num_sectors;
1897 if (tw_dev->sector_count > tw_dev->max_sector_count)
1898 tw_dev->max_sector_count = tw_dev->sector_count;
1899
1900
1901 if (srb) {
1902 tw_dev->sgl_entries = scsi_sg_count(tw_dev->srb[request_id]);
1903 if (tw_dev->sgl_entries > tw_dev->max_sgl_entries)
1904 tw_dev->max_sgl_entries = tw_dev->sgl_entries;
1905 }
1906
1907
1908 if (srb) {
1909 retval = twa_post_command_packet(tw_dev, request_id, 0);
1910 } else {
1911 twa_post_command_packet(tw_dev, request_id, 1);
1912 retval = 0;
1913 }
1914out:
1915 return retval;
1916}
1917
1918
1919static void twa_scsiop_execute_scsi_complete(TW_Device_Extension *tw_dev, int request_id)
1920{
1921 struct scsi_cmnd *cmd = tw_dev->srb[request_id];
1922
1923 if (scsi_bufflen(cmd) < TW_MIN_SGL_LENGTH &&
1924 (cmd->sc_data_direction == DMA_FROM_DEVICE ||
1925 cmd->sc_data_direction == DMA_BIDIRECTIONAL)) {
1926 if (scsi_sg_count(cmd) == 1) {
1927 void *buf = tw_dev->generic_buffer_virt[request_id];
1928
1929 scsi_sg_copy_from_buffer(cmd, buf, TW_SECTOR_SIZE);
1930 }
1931 }
1932}
1933
1934
1935static void __twa_shutdown(TW_Device_Extension *tw_dev)
1936{
1937
1938 TW_DISABLE_INTERRUPTS(tw_dev);
1939
1940
1941 free_irq(tw_dev->tw_pci_dev->irq, tw_dev);
1942
1943 printk(KERN_WARNING "3w-9xxx: Shutting down host %d.\n", tw_dev->host->host_no);
1944
1945
1946 if (twa_initconnection(tw_dev, 1, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL)) {
1947 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x31, "Connection shutdown failed");
1948 } else {
1949 printk(KERN_WARNING "3w-9xxx: Shutdown complete.\n");
1950 }
1951
1952
1953 TW_CLEAR_ALL_INTERRUPTS(tw_dev);
1954}
1955
1956
1957static void twa_shutdown(struct pci_dev *pdev)
1958{
1959 struct Scsi_Host *host = pci_get_drvdata(pdev);
1960 TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata;
1961
1962 __twa_shutdown(tw_dev);
1963}
1964
1965
1966static char *twa_string_lookup(twa_message_type *table, unsigned int code)
1967{
1968 int index;
1969
1970 for (index = 0; ((code != table[index].code) &&
1971 (table[index].text != (char *)0)); index++);
1972 return(table[index].text);
1973}
1974
1975
1976static void twa_unmap_scsi_data(TW_Device_Extension *tw_dev, int request_id)
1977{
1978 struct scsi_cmnd *cmd = tw_dev->srb[request_id];
1979
1980 scsi_dma_unmap(cmd);
1981}
1982
1983
1984static struct scsi_host_template driver_template = {
1985 .module = THIS_MODULE,
1986 .name = "3ware 9000 Storage Controller",
1987 .queuecommand = twa_scsi_queue,
1988 .eh_host_reset_handler = twa_scsi_eh_reset,
1989 .bios_param = twa_scsi_biosparam,
1990 .change_queue_depth = twa_change_queue_depth,
1991 .can_queue = TW_Q_LENGTH-2,
1992 .this_id = -1,
1993 .sg_tablesize = TW_APACHE_MAX_SGL_LENGTH,
1994 .max_sectors = TW_MAX_SECTORS,
1995 .cmd_per_lun = TW_MAX_CMDS_PER_LUN,
1996 .use_clustering = ENABLE_CLUSTERING,
1997 .shost_attrs = twa_host_attrs,
1998 .emulated = 1
1999};
2000
2001
2002static int __devinit twa_probe(struct pci_dev *pdev, const struct pci_device_id *dev_id)
2003{
2004 struct Scsi_Host *host = NULL;
2005 TW_Device_Extension *tw_dev;
2006 unsigned long mem_addr, mem_len;
2007 int retval = -ENODEV;
2008
2009 retval = pci_enable_device(pdev);
2010 if (retval) {
2011 TW_PRINTK(host, TW_DRIVER, 0x34, "Failed to enable pci device");
2012 goto out_disable_device;
2013 }
2014
2015 pci_set_master(pdev);
2016 pci_try_set_mwi(pdev);
2017
2018 if (pci_set_dma_mask(pdev, DMA_64BIT_MASK)
2019 || pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK))
2020 if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)
2021 || pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK)) {
2022 TW_PRINTK(host, TW_DRIVER, 0x23, "Failed to set dma mask");
2023 retval = -ENODEV;
2024 goto out_disable_device;
2025 }
2026
2027 host = scsi_host_alloc(&driver_template, sizeof(TW_Device_Extension));
2028 if (!host) {
2029 TW_PRINTK(host, TW_DRIVER, 0x24, "Failed to allocate memory for device extension");
2030 retval = -ENOMEM;
2031 goto out_disable_device;
2032 }
2033 tw_dev = (TW_Device_Extension *)host->hostdata;
2034
2035
2036 tw_dev->host = host;
2037 tw_dev->tw_pci_dev = pdev;
2038
2039 if (twa_initialize_device_extension(tw_dev)) {
2040 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x25, "Failed to initialize device extension");
2041 goto out_free_device_extension;
2042 }
2043
2044
2045 retval = pci_request_regions(pdev, "3w-9xxx");
2046 if (retval) {
2047 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x26, "Failed to get mem region");
2048 goto out_free_device_extension;
2049 }
2050
2051 if (pdev->device == PCI_DEVICE_ID_3WARE_9000) {
2052 mem_addr = pci_resource_start(pdev, 1);
2053 mem_len = pci_resource_len(pdev, 1);
2054 } else {
2055 mem_addr = pci_resource_start(pdev, 2);
2056 mem_len = pci_resource_len(pdev, 2);
2057 }
2058
2059
2060 tw_dev->base_addr = ioremap(mem_addr, mem_len);
2061 if (!tw_dev->base_addr) {
2062 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x35, "Failed to ioremap");
2063 goto out_release_mem_region;
2064 }
2065
2066
2067 TW_DISABLE_INTERRUPTS(tw_dev);
2068
2069
2070 if (twa_reset_sequence(tw_dev, 0))
2071 goto out_iounmap;
2072
2073
2074 if ((pdev->device == PCI_DEVICE_ID_3WARE_9650SE) ||
2075 (pdev->device == PCI_DEVICE_ID_3WARE_9690SA))
2076 host->max_id = TW_MAX_UNITS_9650SE;
2077 else
2078 host->max_id = TW_MAX_UNITS;
2079
2080 host->max_cmd_len = TW_MAX_CDB_LEN;
2081
2082
2083 host->max_lun = TW_MAX_LUNS(tw_dev->tw_compat_info.working_srl);
2084 host->max_channel = 0;
2085
2086
2087 retval = scsi_add_host(host, &pdev->dev);
2088 if (retval) {
2089 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x27, "scsi add host failed");
2090 goto out_iounmap;
2091 }
2092
2093 pci_set_drvdata(pdev, host);
2094
2095 printk(KERN_WARNING "3w-9xxx: scsi%d: Found a 3ware 9000 Storage Controller at 0x%lx, IRQ: %d.\n",
2096 host->host_no, mem_addr, pdev->irq);
2097 printk(KERN_WARNING "3w-9xxx: scsi%d: Firmware %s, BIOS %s, Ports: %d.\n",
2098 host->host_no,
2099 (char *)twa_get_param(tw_dev, 0, TW_VERSION_TABLE,
2100 TW_PARAM_FWVER, TW_PARAM_FWVER_LENGTH),
2101 (char *)twa_get_param(tw_dev, 1, TW_VERSION_TABLE,
2102 TW_PARAM_BIOSVER, TW_PARAM_BIOSVER_LENGTH),
2103 le32_to_cpu(*(int *)twa_get_param(tw_dev, 2, TW_INFORMATION_TABLE,
2104 TW_PARAM_PORTCOUNT, TW_PARAM_PORTCOUNT_LENGTH)));
2105
2106
2107 if (use_msi && (pdev->device != PCI_DEVICE_ID_3WARE_9000) &&
2108 !pci_enable_msi(pdev))
2109 set_bit(TW_USING_MSI, &tw_dev->flags);
2110
2111
2112 retval = request_irq(pdev->irq, twa_interrupt, IRQF_SHARED, "3w-9xxx", tw_dev);
2113 if (retval) {
2114 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x30, "Error requesting IRQ");
2115 goto out_remove_host;
2116 }
2117
2118 twa_device_extension_list[twa_device_extension_count] = tw_dev;
2119 twa_device_extension_count++;
2120
2121
2122 TW_ENABLE_AND_CLEAR_INTERRUPTS(tw_dev);
2123
2124
2125 scsi_scan_host(host);
2126
2127 if (twa_major == -1) {
2128 if ((twa_major = register_chrdev (0, "twa", &twa_fops)) < 0)
2129 TW_PRINTK(host, TW_DRIVER, 0x29, "Failed to register character device");
2130 }
2131 return 0;
2132
2133out_remove_host:
2134 if (test_bit(TW_USING_MSI, &tw_dev->flags))
2135 pci_disable_msi(pdev);
2136 scsi_remove_host(host);
2137out_iounmap:
2138 iounmap(tw_dev->base_addr);
2139out_release_mem_region:
2140 pci_release_regions(pdev);
2141out_free_device_extension:
2142 twa_free_device_extension(tw_dev);
2143 scsi_host_put(host);
2144out_disable_device:
2145 pci_disable_device(pdev);
2146
2147 return retval;
2148}
2149
2150
2151static void twa_remove(struct pci_dev *pdev)
2152{
2153 struct Scsi_Host *host = pci_get_drvdata(pdev);
2154 TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata;
2155
2156 scsi_remove_host(tw_dev->host);
2157
2158
2159 if (twa_major >= 0) {
2160 unregister_chrdev(twa_major, "twa");
2161 twa_major = -1;
2162 }
2163
2164
2165 __twa_shutdown(tw_dev);
2166
2167
2168 if (test_bit(TW_USING_MSI, &tw_dev->flags))
2169 pci_disable_msi(pdev);
2170
2171
2172 iounmap(tw_dev->base_addr);
2173
2174
2175 pci_release_regions(pdev);
2176
2177
2178 twa_free_device_extension(tw_dev);
2179
2180 scsi_host_put(tw_dev->host);
2181 pci_disable_device(pdev);
2182 twa_device_extension_count--;
2183}
2184
2185
2186static struct pci_device_id twa_pci_tbl[] __devinitdata = {
2187 { PCI_VENDOR_ID_3WARE, PCI_DEVICE_ID_3WARE_9000,
2188 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
2189 { PCI_VENDOR_ID_3WARE, PCI_DEVICE_ID_3WARE_9550SX,
2190 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
2191 { PCI_VENDOR_ID_3WARE, PCI_DEVICE_ID_3WARE_9650SE,
2192 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
2193 { PCI_VENDOR_ID_3WARE, PCI_DEVICE_ID_3WARE_9690SA,
2194 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
2195 { }
2196};
2197MODULE_DEVICE_TABLE(pci, twa_pci_tbl);
2198
2199
2200static struct pci_driver twa_driver = {
2201 .name = "3w-9xxx",
2202 .id_table = twa_pci_tbl,
2203 .probe = twa_probe,
2204 .remove = twa_remove,
2205 .shutdown = twa_shutdown
2206};
2207
2208
2209static int __init twa_init(void)
2210{
2211 printk(KERN_WARNING "3ware 9000 Storage Controller device driver for Linux v%s.\n", TW_DRIVER_VERSION);
2212
2213 return pci_register_driver(&twa_driver);
2214}
2215
2216
2217static void __exit twa_exit(void)
2218{
2219 pci_unregister_driver(&twa_driver);
2220}
2221
2222module_init(twa_init);
2223module_exit(twa_exit);
2224