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