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#include <linux/module.h>
54#include <linux/reboot.h>
55#include <linux/spinlock.h>
56#include <linux/interrupt.h>
57#include <linux/moduleparam.h>
58#include <linux/errno.h>
59#include <linux/types.h>
60#include <linux/delay.h>
61#include <linux/pci.h>
62#include <linux/time.h>
63#include <linux/mutex.h>
64#include <linux/slab.h>
65#include <asm/io.h>
66#include <asm/irq.h>
67#include <linux/uaccess.h>
68#include <scsi/scsi.h>
69#include <scsi/scsi_host.h>
70#include <scsi/scsi_tcq.h>
71#include <scsi/scsi_cmnd.h>
72#include "3w-sas.h"
73
74
75#define TW_DRIVER_VERSION "3.26.02.000"
76static DEFINE_MUTEX(twl_chrdev_mutex);
77static TW_Device_Extension *twl_device_extension_list[TW_MAX_SLOT];
78static unsigned int twl_device_extension_count;
79static int twl_major = -1;
80extern struct timezone sys_tz;
81
82
83MODULE_AUTHOR ("LSI");
84MODULE_DESCRIPTION ("LSI 3ware SAS/SATA-RAID Linux Driver");
85MODULE_LICENSE("GPL");
86MODULE_VERSION(TW_DRIVER_VERSION);
87
88static int use_msi;
89module_param(use_msi, int, S_IRUGO);
90MODULE_PARM_DESC(use_msi, "Use Message Signaled Interrupts. Default: 0");
91
92
93static int twl_reset_device_extension(TW_Device_Extension *tw_dev, int ioctl_reset);
94
95
96
97
98static ssize_t twl_sysfs_aen_read(struct file *filp, struct kobject *kobj,
99 struct bin_attribute *bin_attr,
100 char *outbuf, loff_t offset, size_t count)
101{
102 struct device *dev = container_of(kobj, struct device, kobj);
103 struct Scsi_Host *shost = class_to_shost(dev);
104 TW_Device_Extension *tw_dev = (TW_Device_Extension *)shost->hostdata;
105 unsigned long flags = 0;
106 ssize_t ret;
107
108 if (!capable(CAP_SYS_ADMIN))
109 return -EACCES;
110
111 spin_lock_irqsave(tw_dev->host->host_lock, flags);
112 ret = memory_read_from_buffer(outbuf, count, &offset, tw_dev->event_queue[0], sizeof(TW_Event) * TW_Q_LENGTH);
113 spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
114
115 return ret;
116}
117
118
119static struct bin_attribute twl_sysfs_aen_read_attr = {
120 .attr = {
121 .name = "3ware_aen_read",
122 .mode = S_IRUSR,
123 },
124 .size = 0,
125 .read = twl_sysfs_aen_read
126};
127
128
129static ssize_t twl_sysfs_compat_info(struct file *filp, struct kobject *kobj,
130 struct bin_attribute *bin_attr,
131 char *outbuf, loff_t offset, size_t count)
132{
133 struct device *dev = container_of(kobj, struct device, kobj);
134 struct Scsi_Host *shost = class_to_shost(dev);
135 TW_Device_Extension *tw_dev = (TW_Device_Extension *)shost->hostdata;
136 unsigned long flags = 0;
137 ssize_t ret;
138
139 if (!capable(CAP_SYS_ADMIN))
140 return -EACCES;
141
142 spin_lock_irqsave(tw_dev->host->host_lock, flags);
143 ret = memory_read_from_buffer(outbuf, count, &offset, &tw_dev->tw_compat_info, sizeof(TW_Compatibility_Info));
144 spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
145
146 return ret;
147}
148
149
150static struct bin_attribute twl_sysfs_compat_info_attr = {
151 .attr = {
152 .name = "3ware_compat_info",
153 .mode = S_IRUSR,
154 },
155 .size = 0,
156 .read = twl_sysfs_compat_info
157};
158
159
160static ssize_t twl_show_stats(struct device *dev,
161 struct device_attribute *attr, char *buf)
162{
163 struct Scsi_Host *host = class_to_shost(dev);
164 TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata;
165 unsigned long flags = 0;
166 ssize_t len;
167
168 spin_lock_irqsave(tw_dev->host->host_lock, flags);
169 len = snprintf(buf, PAGE_SIZE, "3w-sas Driver version: %s\n"
170 "Current commands posted: %4d\n"
171 "Max commands posted: %4d\n"
172 "Last sgl length: %4d\n"
173 "Max sgl length: %4d\n"
174 "Last sector count: %4d\n"
175 "Max sector count: %4d\n"
176 "SCSI Host Resets: %4d\n"
177 "AEN's: %4d\n",
178 TW_DRIVER_VERSION,
179 tw_dev->posted_request_count,
180 tw_dev->max_posted_request_count,
181 tw_dev->sgl_entries,
182 tw_dev->max_sgl_entries,
183 tw_dev->sector_count,
184 tw_dev->max_sector_count,
185 tw_dev->num_resets,
186 tw_dev->aen_count);
187 spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
188 return len;
189}
190
191
192static struct device_attribute twl_host_stats_attr = {
193 .attr = {
194 .name = "3ware_stats",
195 .mode = S_IRUGO,
196 },
197 .show = twl_show_stats
198};
199
200
201static struct device_attribute *twl_host_attrs[] = {
202 &twl_host_stats_attr,
203 NULL,
204};
205
206
207static char *twl_aen_severity_lookup(unsigned char severity_code)
208{
209 char *retval = NULL;
210
211 if ((severity_code < (unsigned char) TW_AEN_SEVERITY_ERROR) ||
212 (severity_code > (unsigned char) TW_AEN_SEVERITY_DEBUG))
213 goto out;
214
215 retval = twl_aen_severity_table[severity_code];
216out:
217 return retval;
218}
219
220
221static void twl_aen_queue_event(TW_Device_Extension *tw_dev, TW_Command_Apache_Header *header)
222{
223 u32 local_time;
224 TW_Event *event;
225 unsigned short aen;
226 char host[16];
227 char *error_str;
228
229 tw_dev->aen_count++;
230
231
232 event = tw_dev->event_queue[tw_dev->error_index];
233
234 host[0] = '\0';
235 if (tw_dev->host)
236 sprintf(host, " scsi%d:", tw_dev->host->host_no);
237
238 aen = le16_to_cpu(header->status_block.error);
239 memset(event, 0, sizeof(TW_Event));
240
241 event->severity = TW_SEV_OUT(header->status_block.severity__reserved);
242
243 local_time = (u32)(ktime_get_real_seconds() - (sys_tz.tz_minuteswest * 60));
244 event->time_stamp_sec = local_time;
245 event->aen_code = aen;
246 event->retrieved = TW_AEN_NOT_RETRIEVED;
247 event->sequence_id = tw_dev->error_sequence_id;
248 tw_dev->error_sequence_id++;
249
250
251 error_str = &(header->err_specific_desc[strlen(header->err_specific_desc)+1]);
252
253 header->err_specific_desc[sizeof(header->err_specific_desc) - 1] = '\0';
254 event->parameter_len = strlen(header->err_specific_desc);
255 memcpy(event->parameter_data, header->err_specific_desc, event->parameter_len + 1 + strlen(error_str));
256 if (event->severity != TW_AEN_SEVERITY_DEBUG)
257 printk(KERN_WARNING "3w-sas:%s AEN: %s (0x%02X:0x%04X): %s:%s.\n",
258 host,
259 twl_aen_severity_lookup(TW_SEV_OUT(header->status_block.severity__reserved)),
260 TW_MESSAGE_SOURCE_CONTROLLER_EVENT, aen, error_str,
261 header->err_specific_desc);
262 else
263 tw_dev->aen_count--;
264
265 tw_dev->error_index = (tw_dev->error_index + 1 ) % TW_Q_LENGTH;
266}
267
268
269static int twl_post_command_packet(TW_Device_Extension *tw_dev, int request_id)
270{
271 dma_addr_t command_que_value;
272
273 command_que_value = tw_dev->command_packet_phys[request_id];
274 command_que_value += TW_COMMAND_OFFSET;
275
276
277 writel((u32)((u64)command_que_value >> 32), TWL_HIBQPH_REG_ADDR(tw_dev));
278
279 writel((u32)(command_que_value | TWL_PULL_MODE), TWL_HIBQPL_REG_ADDR(tw_dev));
280
281 tw_dev->state[request_id] = TW_S_POSTED;
282 tw_dev->posted_request_count++;
283 if (tw_dev->posted_request_count > tw_dev->max_posted_request_count)
284 tw_dev->max_posted_request_count = tw_dev->posted_request_count;
285
286 return 0;
287}
288
289
290static int twl_scsiop_execute_scsi(TW_Device_Extension *tw_dev, int request_id, char *cdb, int use_sg, TW_SG_Entry_ISO *sglistarg)
291{
292 TW_Command_Full *full_command_packet;
293 TW_Command_Apache *command_packet;
294 int i, sg_count;
295 struct scsi_cmnd *srb = NULL;
296 struct scatterlist *sglist = NULL, *sg;
297 int retval = 1;
298
299 if (tw_dev->srb[request_id]) {
300 srb = tw_dev->srb[request_id];
301 if (scsi_sglist(srb))
302 sglist = scsi_sglist(srb);
303 }
304
305
306 full_command_packet = tw_dev->command_packet_virt[request_id];
307 full_command_packet->header.header_desc.size_header = 128;
308 full_command_packet->header.status_block.error = 0;
309 full_command_packet->header.status_block.severity__reserved = 0;
310
311 command_packet = &full_command_packet->command.newcommand;
312 command_packet->status = 0;
313 command_packet->opcode__reserved = TW_OPRES_IN(0, TW_OP_EXECUTE_SCSI);
314
315
316 if (!cdb)
317 memcpy(command_packet->cdb, srb->cmnd, TW_MAX_CDB_LEN);
318 else
319 memcpy(command_packet->cdb, cdb, TW_MAX_CDB_LEN);
320
321 if (srb) {
322 command_packet->unit = srb->device->id;
323 command_packet->request_id__lunl =
324 cpu_to_le16(TW_REQ_LUN_IN(srb->device->lun, request_id));
325 } else {
326 command_packet->request_id__lunl =
327 cpu_to_le16(TW_REQ_LUN_IN(0, request_id));
328 command_packet->unit = 0;
329 }
330
331 command_packet->sgl_offset = 16;
332
333 if (!sglistarg) {
334
335 if (scsi_sg_count(srb)) {
336 sg_count = scsi_dma_map(srb);
337 if (sg_count <= 0)
338 goto out;
339
340 scsi_for_each_sg(srb, sg, sg_count, i) {
341 command_packet->sg_list[i].address = TW_CPU_TO_SGL(sg_dma_address(sg));
342 command_packet->sg_list[i].length = TW_CPU_TO_SGL(sg_dma_len(sg));
343 }
344 command_packet->sgl_entries__lunh = cpu_to_le16(TW_REQ_LUN_IN((srb->device->lun >> 4), scsi_sg_count(tw_dev->srb[request_id])));
345 }
346 } else {
347
348 for (i = 0; i < use_sg; i++) {
349 command_packet->sg_list[i].address = TW_CPU_TO_SGL(sglistarg[i].address);
350 command_packet->sg_list[i].length = TW_CPU_TO_SGL(sglistarg[i].length);
351 }
352 command_packet->sgl_entries__lunh = cpu_to_le16(TW_REQ_LUN_IN(0, use_sg));
353 }
354
355
356 if (srb) {
357 tw_dev->sector_count = scsi_bufflen(srb) / 512;
358 if (tw_dev->sector_count > tw_dev->max_sector_count)
359 tw_dev->max_sector_count = tw_dev->sector_count;
360 tw_dev->sgl_entries = scsi_sg_count(srb);
361 if (tw_dev->sgl_entries > tw_dev->max_sgl_entries)
362 tw_dev->max_sgl_entries = tw_dev->sgl_entries;
363 }
364
365
366 retval = twl_post_command_packet(tw_dev, request_id);
367
368out:
369 return retval;
370}
371
372
373static int twl_aen_read_queue(TW_Device_Extension *tw_dev, int request_id)
374{
375 char cdb[TW_MAX_CDB_LEN];
376 TW_SG_Entry_ISO sglist[1];
377 TW_Command_Full *full_command_packet;
378 int retval = 1;
379
380 full_command_packet = tw_dev->command_packet_virt[request_id];
381 memset(full_command_packet, 0, sizeof(TW_Command_Full));
382
383
384 memset(&cdb, 0, TW_MAX_CDB_LEN);
385 cdb[0] = REQUEST_SENSE;
386 cdb[4] = TW_ALLOCATION_LENGTH;
387
388
389 memset(&sglist, 0, sizeof(TW_SG_Entry_ISO));
390 sglist[0].length = TW_SECTOR_SIZE;
391 sglist[0].address = tw_dev->generic_buffer_phys[request_id];
392
393
394 tw_dev->srb[request_id] = NULL;
395
396
397 if (twl_scsiop_execute_scsi(tw_dev, request_id, cdb, 1, sglist)) {
398 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x2, "Post failed while reading AEN queue");
399 goto out;
400 }
401 retval = 0;
402out:
403 return retval;
404}
405
406
407static void twl_aen_sync_time(TW_Device_Extension *tw_dev, int request_id)
408{
409 u32 schedulertime;
410 TW_Command_Full *full_command_packet;
411 TW_Command *command_packet;
412 TW_Param_Apache *param;
413 time64_t local_time;
414
415
416 full_command_packet = tw_dev->command_packet_virt[request_id];
417 memset(full_command_packet, 0, sizeof(TW_Command_Full));
418 command_packet = &full_command_packet->command.oldcommand;
419 command_packet->opcode__sgloffset = TW_OPSGL_IN(2, TW_OP_SET_PARAM);
420 command_packet->request_id = request_id;
421 command_packet->byte8_offset.param.sgl[0].address = TW_CPU_TO_SGL(tw_dev->generic_buffer_phys[request_id]);
422 command_packet->byte8_offset.param.sgl[0].length = TW_CPU_TO_SGL(TW_SECTOR_SIZE);
423 command_packet->size = TW_COMMAND_SIZE;
424 command_packet->byte6_offset.parameter_count = cpu_to_le16(1);
425
426
427 param = (TW_Param_Apache *)tw_dev->generic_buffer_virt[request_id];
428 memset(param, 0, TW_SECTOR_SIZE);
429 param->table_id = cpu_to_le16(TW_TIMEKEEP_TABLE | 0x8000);
430 param->parameter_id = cpu_to_le16(0x3);
431 param->parameter_size_bytes = cpu_to_le16(4);
432
433
434
435 local_time = (ktime_get_real_seconds() - (sys_tz.tz_minuteswest * 60));
436 div_u64_rem(local_time - (3 * 86400), 604800, &schedulertime);
437 schedulertime = cpu_to_le32(schedulertime);
438
439 memcpy(param->data, &schedulertime, sizeof(u32));
440
441
442 tw_dev->srb[request_id] = NULL;
443
444
445 twl_post_command_packet(tw_dev, request_id);
446}
447
448
449static void twl_get_request_id(TW_Device_Extension *tw_dev, int *request_id)
450{
451 *request_id = tw_dev->free_queue[tw_dev->free_head];
452 tw_dev->free_head = (tw_dev->free_head + 1) % TW_Q_LENGTH;
453 tw_dev->state[*request_id] = TW_S_STARTED;
454}
455
456
457static void twl_free_request_id(TW_Device_Extension *tw_dev, int request_id)
458{
459 tw_dev->free_queue[tw_dev->free_tail] = request_id;
460 tw_dev->state[request_id] = TW_S_FINISHED;
461 tw_dev->free_tail = (tw_dev->free_tail + 1) % TW_Q_LENGTH;
462}
463
464
465static int twl_aen_complete(TW_Device_Extension *tw_dev, int request_id)
466{
467 TW_Command_Full *full_command_packet;
468 TW_Command *command_packet;
469 TW_Command_Apache_Header *header;
470 unsigned short aen;
471 int retval = 1;
472
473 header = (TW_Command_Apache_Header *)tw_dev->generic_buffer_virt[request_id];
474 tw_dev->posted_request_count--;
475 aen = le16_to_cpu(header->status_block.error);
476 full_command_packet = tw_dev->command_packet_virt[request_id];
477 command_packet = &full_command_packet->command.oldcommand;
478
479
480 if (TW_OP_OUT(command_packet->opcode__sgloffset) == TW_OP_SET_PARAM) {
481
482 if (twl_aen_read_queue(tw_dev, request_id))
483 goto out2;
484 else {
485 retval = 0;
486 goto out;
487 }
488 }
489
490 switch (aen) {
491 case TW_AEN_QUEUE_EMPTY:
492
493 break;
494 case TW_AEN_SYNC_TIME_WITH_HOST:
495 twl_aen_sync_time(tw_dev, request_id);
496 retval = 0;
497 goto out;
498 default:
499 twl_aen_queue_event(tw_dev, header);
500
501
502 if (twl_aen_read_queue(tw_dev, request_id))
503 goto out2;
504 else {
505 retval = 0;
506 goto out;
507 }
508 }
509 retval = 0;
510out2:
511 tw_dev->state[request_id] = TW_S_COMPLETED;
512 twl_free_request_id(tw_dev, request_id);
513 clear_bit(TW_IN_ATTENTION_LOOP, &tw_dev->flags);
514out:
515 return retval;
516}
517
518
519static int twl_poll_response(TW_Device_Extension *tw_dev, int request_id, int seconds)
520{
521 unsigned long before;
522 dma_addr_t mfa;
523 u32 regh, regl;
524 u32 response;
525 int retval = 1;
526 int found = 0;
527
528 before = jiffies;
529
530 while (!found) {
531 if (sizeof(dma_addr_t) > 4) {
532 regh = readl(TWL_HOBQPH_REG_ADDR(tw_dev));
533 regl = readl(TWL_HOBQPL_REG_ADDR(tw_dev));
534 mfa = ((u64)regh << 32) | regl;
535 } else
536 mfa = readl(TWL_HOBQPL_REG_ADDR(tw_dev));
537
538 response = (u32)mfa;
539
540 if (TW_RESID_OUT(response) == request_id)
541 found = 1;
542
543 if (time_after(jiffies, before + HZ * seconds))
544 goto out;
545
546 msleep(50);
547 }
548 retval = 0;
549out:
550 return retval;
551}
552
553
554static int twl_aen_drain_queue(TW_Device_Extension *tw_dev, int no_check_reset)
555{
556 int request_id = 0;
557 char cdb[TW_MAX_CDB_LEN];
558 TW_SG_Entry_ISO sglist[1];
559 int finished = 0, count = 0;
560 TW_Command_Full *full_command_packet;
561 TW_Command_Apache_Header *header;
562 unsigned short aen;
563 int first_reset = 0, queue = 0, retval = 1;
564
565 if (no_check_reset)
566 first_reset = 0;
567 else
568 first_reset = 1;
569
570 full_command_packet = tw_dev->command_packet_virt[request_id];
571 memset(full_command_packet, 0, sizeof(TW_Command_Full));
572
573
574 memset(&cdb, 0, TW_MAX_CDB_LEN);
575 cdb[0] = REQUEST_SENSE;
576 cdb[4] = TW_ALLOCATION_LENGTH;
577
578
579 memset(&sglist, 0, sizeof(TW_SG_Entry_ISO));
580 sglist[0].length = TW_SECTOR_SIZE;
581 sglist[0].address = tw_dev->generic_buffer_phys[request_id];
582
583
584 tw_dev->srb[request_id] = NULL;
585
586 do {
587
588 if (twl_scsiop_execute_scsi(tw_dev, request_id, cdb, 1, sglist)) {
589 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x3, "Error posting request sense");
590 goto out;
591 }
592
593
594 if (twl_poll_response(tw_dev, request_id, 30)) {
595 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x4, "No valid response while draining AEN queue");
596 tw_dev->posted_request_count--;
597 goto out;
598 }
599
600 tw_dev->posted_request_count--;
601 header = (TW_Command_Apache_Header *)tw_dev->generic_buffer_virt[request_id];
602 aen = le16_to_cpu(header->status_block.error);
603 queue = 0;
604 count++;
605
606 switch (aen) {
607 case TW_AEN_QUEUE_EMPTY:
608 if (first_reset != 1)
609 goto out;
610 else
611 finished = 1;
612 break;
613 case TW_AEN_SOFT_RESET:
614 if (first_reset == 0)
615 first_reset = 1;
616 else
617 queue = 1;
618 break;
619 case TW_AEN_SYNC_TIME_WITH_HOST:
620 break;
621 default:
622 queue = 1;
623 }
624
625
626 if (queue)
627 twl_aen_queue_event(tw_dev, header);
628 } while ((finished == 0) && (count < TW_MAX_AEN_DRAIN));
629
630 if (count == TW_MAX_AEN_DRAIN)
631 goto out;
632
633 retval = 0;
634out:
635 tw_dev->state[request_id] = TW_S_INITIAL;
636 return retval;
637}
638
639
640static int twl_allocate_memory(TW_Device_Extension *tw_dev, int size, int which)
641{
642 int i;
643 dma_addr_t dma_handle;
644 unsigned long *cpu_addr;
645 int retval = 1;
646
647 cpu_addr = pci_zalloc_consistent(tw_dev->tw_pci_dev, size * TW_Q_LENGTH,
648 &dma_handle);
649 if (!cpu_addr) {
650 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x5, "Memory allocation failed");
651 goto out;
652 }
653
654 for (i = 0; i < TW_Q_LENGTH; i++) {
655 switch(which) {
656 case 0:
657 tw_dev->command_packet_phys[i] = dma_handle+(i*size);
658 tw_dev->command_packet_virt[i] = (TW_Command_Full *)((unsigned char *)cpu_addr + (i*size));
659 break;
660 case 1:
661 tw_dev->generic_buffer_phys[i] = dma_handle+(i*size);
662 tw_dev->generic_buffer_virt[i] = (unsigned long *)((unsigned char *)cpu_addr + (i*size));
663 break;
664 case 2:
665 tw_dev->sense_buffer_phys[i] = dma_handle+(i*size);
666 tw_dev->sense_buffer_virt[i] = (TW_Command_Apache_Header *)((unsigned char *)cpu_addr + (i*size));
667 break;
668 }
669 }
670 retval = 0;
671out:
672 return retval;
673}
674
675
676static void twl_load_sgl(TW_Device_Extension *tw_dev, TW_Command_Full *full_command_packet, int request_id, dma_addr_t dma_handle, int length)
677{
678 TW_Command *oldcommand;
679 TW_Command_Apache *newcommand;
680 TW_SG_Entry_ISO *sgl;
681 unsigned int pae = 0;
682
683 if ((sizeof(long) < 8) && (sizeof(dma_addr_t) > 4))
684 pae = 1;
685
686 if (TW_OP_OUT(full_command_packet->command.newcommand.opcode__reserved) == TW_OP_EXECUTE_SCSI) {
687 newcommand = &full_command_packet->command.newcommand;
688 newcommand->request_id__lunl =
689 cpu_to_le16(TW_REQ_LUN_IN(TW_LUN_OUT(newcommand->request_id__lunl), request_id));
690 if (length) {
691 newcommand->sg_list[0].address = TW_CPU_TO_SGL(dma_handle + sizeof(TW_Ioctl_Buf_Apache) - 1);
692 newcommand->sg_list[0].length = TW_CPU_TO_SGL(length);
693 }
694 newcommand->sgl_entries__lunh =
695 cpu_to_le16(TW_REQ_LUN_IN(TW_LUN_OUT(newcommand->sgl_entries__lunh), length ? 1 : 0));
696 } else {
697 oldcommand = &full_command_packet->command.oldcommand;
698 oldcommand->request_id = request_id;
699
700 if (TW_SGL_OUT(oldcommand->opcode__sgloffset)) {
701
702 sgl = (TW_SG_Entry_ISO *)((u32 *)oldcommand+oldcommand->size - (sizeof(TW_SG_Entry_ISO)/4) + pae + (sizeof(dma_addr_t) > 4 ? 1 : 0));
703 sgl->address = TW_CPU_TO_SGL(dma_handle + sizeof(TW_Ioctl_Buf_Apache) - 1);
704 sgl->length = TW_CPU_TO_SGL(length);
705 oldcommand->size += pae;
706 oldcommand->size += sizeof(dma_addr_t) > 4 ? 1 : 0;
707 }
708 }
709}
710
711
712
713static long twl_chrdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
714{
715 long timeout;
716 unsigned long *cpu_addr, data_buffer_length_adjusted = 0, flags = 0;
717 dma_addr_t dma_handle;
718 int request_id = 0;
719 TW_Ioctl_Driver_Command driver_command;
720 struct inode *inode = file_inode(file);
721 TW_Ioctl_Buf_Apache *tw_ioctl;
722 TW_Command_Full *full_command_packet;
723 TW_Device_Extension *tw_dev = twl_device_extension_list[iminor(inode)];
724 int retval = -EFAULT;
725 void __user *argp = (void __user *)arg;
726
727 mutex_lock(&twl_chrdev_mutex);
728
729
730 if (mutex_lock_interruptible(&tw_dev->ioctl_lock)) {
731 retval = -EINTR;
732 goto out;
733 }
734
735
736 if (copy_from_user(&driver_command, argp, sizeof(TW_Ioctl_Driver_Command)))
737 goto out2;
738
739
740 if (driver_command.buffer_length > TW_MAX_SECTORS * 2048) {
741 retval = -EINVAL;
742 goto out2;
743 }
744
745
746 data_buffer_length_adjusted = (driver_command.buffer_length + 511) & ~511;
747
748
749 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);
750 if (!cpu_addr) {
751 retval = -ENOMEM;
752 goto out2;
753 }
754
755 tw_ioctl = (TW_Ioctl_Buf_Apache *)cpu_addr;
756
757
758 if (copy_from_user(tw_ioctl, argp, driver_command.buffer_length + sizeof(TW_Ioctl_Buf_Apache) - 1))
759 goto out3;
760
761
762 switch (cmd) {
763 case TW_IOCTL_FIRMWARE_PASS_THROUGH:
764 spin_lock_irqsave(tw_dev->host->host_lock, flags);
765 twl_get_request_id(tw_dev, &request_id);
766
767
768 tw_dev->srb[request_id] = NULL;
769
770
771 tw_dev->chrdev_request_id = request_id;
772
773 full_command_packet = (TW_Command_Full *)&tw_ioctl->firmware_command;
774
775
776 twl_load_sgl(tw_dev, full_command_packet, request_id, dma_handle, data_buffer_length_adjusted);
777
778 memcpy(tw_dev->command_packet_virt[request_id], &(tw_ioctl->firmware_command), sizeof(TW_Command_Full));
779
780
781 twl_post_command_packet(tw_dev, request_id);
782 spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
783
784 timeout = TW_IOCTL_CHRDEV_TIMEOUT*HZ;
785
786
787 timeout = wait_event_timeout(tw_dev->ioctl_wqueue, tw_dev->chrdev_request_id == TW_IOCTL_CHRDEV_FREE, timeout);
788
789
790 if (tw_dev->chrdev_request_id != TW_IOCTL_CHRDEV_FREE) {
791
792 printk(KERN_WARNING "3w-sas: scsi%d: WARNING: (0x%02X:0x%04X): Character ioctl (0x%x) timed out, resetting card.\n",
793 tw_dev->host->host_no, TW_DRIVER, 0x6,
794 cmd);
795 retval = -EIO;
796 twl_reset_device_extension(tw_dev, 1);
797 goto out3;
798 }
799
800
801 memcpy(&(tw_ioctl->firmware_command), tw_dev->command_packet_virt[request_id], sizeof(TW_Command_Full));
802
803
804 spin_lock_irqsave(tw_dev->host->host_lock, flags);
805 tw_dev->posted_request_count--;
806 tw_dev->state[request_id] = TW_S_COMPLETED;
807 twl_free_request_id(tw_dev, request_id);
808 spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
809 break;
810 default:
811 retval = -ENOTTY;
812 goto out3;
813 }
814
815
816 if (copy_to_user(argp, tw_ioctl, sizeof(TW_Ioctl_Buf_Apache) + driver_command.buffer_length - 1) == 0)
817 retval = 0;
818out3:
819
820 dma_free_coherent(&tw_dev->tw_pci_dev->dev, data_buffer_length_adjusted+sizeof(TW_Ioctl_Buf_Apache) - 1, cpu_addr, dma_handle);
821out2:
822 mutex_unlock(&tw_dev->ioctl_lock);
823out:
824 mutex_unlock(&twl_chrdev_mutex);
825 return retval;
826}
827
828
829static int twl_chrdev_open(struct inode *inode, struct file *file)
830{
831 unsigned int minor_number;
832 int retval = -ENODEV;
833
834 if (!capable(CAP_SYS_ADMIN)) {
835 retval = -EACCES;
836 goto out;
837 }
838
839 minor_number = iminor(inode);
840 if (minor_number >= twl_device_extension_count)
841 goto out;
842 retval = 0;
843out:
844 return retval;
845}
846
847
848static const struct file_operations twl_fops = {
849 .owner = THIS_MODULE,
850 .unlocked_ioctl = twl_chrdev_ioctl,
851 .open = twl_chrdev_open,
852 .release = NULL,
853 .llseek = noop_llseek,
854};
855
856
857static int twl_fill_sense(TW_Device_Extension *tw_dev, int i, int request_id, int copy_sense, int print_host)
858{
859 TW_Command_Apache_Header *header;
860 TW_Command_Full *full_command_packet;
861 unsigned short error;
862 char *error_str;
863 int retval = 1;
864
865 header = tw_dev->sense_buffer_virt[i];
866 full_command_packet = tw_dev->command_packet_virt[request_id];
867
868
869 error_str = &(header->err_specific_desc[strlen(header->err_specific_desc) + 1]);
870
871
872 error = le16_to_cpu(header->status_block.error);
873 if ((error != TW_ERROR_LOGICAL_UNIT_NOT_SUPPORTED) && (error != TW_ERROR_UNIT_OFFLINE) && (error != TW_ERROR_INVALID_FIELD_IN_CDB)) {
874 if (print_host)
875 printk(KERN_WARNING "3w-sas: scsi%d: ERROR: (0x%02X:0x%04X): %s:%s.\n",
876 tw_dev->host->host_no,
877 TW_MESSAGE_SOURCE_CONTROLLER_ERROR,
878 header->status_block.error,
879 error_str,
880 header->err_specific_desc);
881 else
882 printk(KERN_WARNING "3w-sas: ERROR: (0x%02X:0x%04X): %s:%s.\n",
883 TW_MESSAGE_SOURCE_CONTROLLER_ERROR,
884 header->status_block.error,
885 error_str,
886 header->err_specific_desc);
887 }
888
889 if (copy_sense) {
890 memcpy(tw_dev->srb[request_id]->sense_buffer, header->sense_data, TW_SENSE_DATA_LENGTH);
891 tw_dev->srb[request_id]->result = (full_command_packet->command.newcommand.status << 1);
892 goto out;
893 }
894out:
895 return retval;
896}
897
898
899static void twl_free_device_extension(TW_Device_Extension *tw_dev)
900{
901 if (tw_dev->command_packet_virt[0])
902 pci_free_consistent(tw_dev->tw_pci_dev,
903 sizeof(TW_Command_Full)*TW_Q_LENGTH,
904 tw_dev->command_packet_virt[0],
905 tw_dev->command_packet_phys[0]);
906
907 if (tw_dev->generic_buffer_virt[0])
908 pci_free_consistent(tw_dev->tw_pci_dev,
909 TW_SECTOR_SIZE*TW_Q_LENGTH,
910 tw_dev->generic_buffer_virt[0],
911 tw_dev->generic_buffer_phys[0]);
912
913 if (tw_dev->sense_buffer_virt[0])
914 pci_free_consistent(tw_dev->tw_pci_dev,
915 sizeof(TW_Command_Apache_Header)*
916 TW_Q_LENGTH,
917 tw_dev->sense_buffer_virt[0],
918 tw_dev->sense_buffer_phys[0]);
919
920 kfree(tw_dev->event_queue[0]);
921}
922
923
924static void *twl_get_param(TW_Device_Extension *tw_dev, int request_id, int table_id, int parameter_id, int parameter_size_bytes)
925{
926 TW_Command_Full *full_command_packet;
927 TW_Command *command_packet;
928 TW_Param_Apache *param;
929 void *retval = NULL;
930
931
932 full_command_packet = tw_dev->command_packet_virt[request_id];
933 memset(full_command_packet, 0, sizeof(TW_Command_Full));
934 command_packet = &full_command_packet->command.oldcommand;
935
936 command_packet->opcode__sgloffset = TW_OPSGL_IN(2, TW_OP_GET_PARAM);
937 command_packet->size = TW_COMMAND_SIZE;
938 command_packet->request_id = request_id;
939 command_packet->byte6_offset.block_count = cpu_to_le16(1);
940
941
942 param = (TW_Param_Apache *)tw_dev->generic_buffer_virt[request_id];
943 memset(param, 0, TW_SECTOR_SIZE);
944 param->table_id = cpu_to_le16(table_id | 0x8000);
945 param->parameter_id = cpu_to_le16(parameter_id);
946 param->parameter_size_bytes = cpu_to_le16(parameter_size_bytes);
947
948 command_packet->byte8_offset.param.sgl[0].address = TW_CPU_TO_SGL(tw_dev->generic_buffer_phys[request_id]);
949 command_packet->byte8_offset.param.sgl[0].length = TW_CPU_TO_SGL(TW_SECTOR_SIZE);
950
951
952 twl_post_command_packet(tw_dev, request_id);
953
954
955 if (twl_poll_response(tw_dev, request_id, 30))
956 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x7, "No valid response during get param")
957 else
958 retval = (void *)&(param->data[0]);
959
960 tw_dev->posted_request_count--;
961 tw_dev->state[request_id] = TW_S_INITIAL;
962
963 return retval;
964}
965
966
967static int twl_initconnection(TW_Device_Extension *tw_dev, int message_credits,
968 u32 set_features, unsigned short current_fw_srl,
969 unsigned short current_fw_arch_id,
970 unsigned short current_fw_branch,
971 unsigned short current_fw_build,
972 unsigned short *fw_on_ctlr_srl,
973 unsigned short *fw_on_ctlr_arch_id,
974 unsigned short *fw_on_ctlr_branch,
975 unsigned short *fw_on_ctlr_build,
976 u32 *init_connect_result)
977{
978 TW_Command_Full *full_command_packet;
979 TW_Initconnect *tw_initconnect;
980 int request_id = 0, retval = 1;
981
982
983 full_command_packet = tw_dev->command_packet_virt[request_id];
984 memset(full_command_packet, 0, sizeof(TW_Command_Full));
985 full_command_packet->header.header_desc.size_header = 128;
986
987 tw_initconnect = (TW_Initconnect *)&full_command_packet->command.oldcommand;
988 tw_initconnect->opcode__reserved = TW_OPRES_IN(0, TW_OP_INIT_CONNECTION);
989 tw_initconnect->request_id = request_id;
990 tw_initconnect->message_credits = cpu_to_le16(message_credits);
991 tw_initconnect->features = set_features;
992
993
994 tw_initconnect->features |= sizeof(dma_addr_t) > 4 ? 1 : 0;
995
996 tw_initconnect->features = cpu_to_le32(tw_initconnect->features);
997
998 if (set_features & TW_EXTENDED_INIT_CONNECT) {
999 tw_initconnect->size = TW_INIT_COMMAND_PACKET_SIZE_EXTENDED;
1000 tw_initconnect->fw_srl = cpu_to_le16(current_fw_srl);
1001 tw_initconnect->fw_arch_id = cpu_to_le16(current_fw_arch_id);
1002 tw_initconnect->fw_branch = cpu_to_le16(current_fw_branch);
1003 tw_initconnect->fw_build = cpu_to_le16(current_fw_build);
1004 } else
1005 tw_initconnect->size = TW_INIT_COMMAND_PACKET_SIZE;
1006
1007
1008 twl_post_command_packet(tw_dev, request_id);
1009
1010
1011 if (twl_poll_response(tw_dev, request_id, 30)) {
1012 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x8, "No valid response during init connection");
1013 } else {
1014 if (set_features & TW_EXTENDED_INIT_CONNECT) {
1015 *fw_on_ctlr_srl = le16_to_cpu(tw_initconnect->fw_srl);
1016 *fw_on_ctlr_arch_id = le16_to_cpu(tw_initconnect->fw_arch_id);
1017 *fw_on_ctlr_branch = le16_to_cpu(tw_initconnect->fw_branch);
1018 *fw_on_ctlr_build = le16_to_cpu(tw_initconnect->fw_build);
1019 *init_connect_result = le32_to_cpu(tw_initconnect->result);
1020 }
1021 retval = 0;
1022 }
1023
1024 tw_dev->posted_request_count--;
1025 tw_dev->state[request_id] = TW_S_INITIAL;
1026
1027 return retval;
1028}
1029
1030
1031static int twl_initialize_device_extension(TW_Device_Extension *tw_dev)
1032{
1033 int i, retval = 1;
1034
1035
1036 if (twl_allocate_memory(tw_dev, sizeof(TW_Command_Full), 0)) {
1037 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x9, "Command packet memory allocation failed");
1038 goto out;
1039 }
1040
1041
1042 if (twl_allocate_memory(tw_dev, TW_SECTOR_SIZE, 1)) {
1043 TW_PRINTK(tw_dev->host, TW_DRIVER, 0xa, "Generic memory allocation failed");
1044 goto out;
1045 }
1046
1047
1048 if (twl_allocate_memory(tw_dev, sizeof(TW_Command_Apache_Header), 2)) {
1049 TW_PRINTK(tw_dev->host, TW_DRIVER, 0xb, "Sense buffer allocation failed");
1050 goto out;
1051 }
1052
1053
1054 tw_dev->event_queue[0] = kcalloc(TW_Q_LENGTH, sizeof(TW_Event), GFP_KERNEL);
1055 if (!tw_dev->event_queue[0]) {
1056 TW_PRINTK(tw_dev->host, TW_DRIVER, 0xc, "Event info memory allocation failed");
1057 goto out;
1058 }
1059
1060 for (i = 0; i < TW_Q_LENGTH; i++) {
1061 tw_dev->event_queue[i] = (TW_Event *)((unsigned char *)tw_dev->event_queue[0] + (i * sizeof(TW_Event)));
1062 tw_dev->free_queue[i] = i;
1063 tw_dev->state[i] = TW_S_INITIAL;
1064 }
1065
1066 tw_dev->free_head = TW_Q_START;
1067 tw_dev->free_tail = TW_Q_START;
1068 tw_dev->error_sequence_id = 1;
1069 tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE;
1070
1071 mutex_init(&tw_dev->ioctl_lock);
1072 init_waitqueue_head(&tw_dev->ioctl_wqueue);
1073
1074 retval = 0;
1075out:
1076 return retval;
1077}
1078
1079
1080static int twl_handle_attention_interrupt(TW_Device_Extension *tw_dev)
1081{
1082 int retval = 1;
1083 u32 request_id, doorbell;
1084
1085
1086 doorbell = readl(TWL_HOBDB_REG_ADDR(tw_dev));
1087
1088
1089 if (doorbell & TWL_DOORBELL_CONTROLLER_ERROR) {
1090 TW_PRINTK(tw_dev->host, TW_DRIVER, 0xd, "Microcontroller Error: clearing");
1091 goto out;
1092 }
1093
1094
1095 if (doorbell & TWL_DOORBELL_ATTENTION_INTERRUPT) {
1096 if (!(test_and_set_bit(TW_IN_ATTENTION_LOOP, &tw_dev->flags))) {
1097 twl_get_request_id(tw_dev, &request_id);
1098 if (twl_aen_read_queue(tw_dev, request_id)) {
1099 tw_dev->state[request_id] = TW_S_COMPLETED;
1100 twl_free_request_id(tw_dev, request_id);
1101 clear_bit(TW_IN_ATTENTION_LOOP, &tw_dev->flags);
1102 }
1103 }
1104 }
1105
1106 retval = 0;
1107out:
1108
1109 TWL_CLEAR_DB_INTERRUPT(tw_dev);
1110
1111
1112 readl(TWL_HOBDBC_REG_ADDR(tw_dev));
1113
1114 return retval;
1115}
1116
1117
1118static irqreturn_t twl_interrupt(int irq, void *dev_instance)
1119{
1120 TW_Device_Extension *tw_dev = (TW_Device_Extension *)dev_instance;
1121 int i, handled = 0, error = 0;
1122 dma_addr_t mfa = 0;
1123 u32 reg, regl, regh, response, request_id = 0;
1124 struct scsi_cmnd *cmd;
1125 TW_Command_Full *full_command_packet;
1126
1127 spin_lock(tw_dev->host->host_lock);
1128
1129
1130 reg = readl(TWL_HISTAT_REG_ADDR(tw_dev));
1131
1132
1133 if (!(reg & TWL_HISTATUS_VALID_INTERRUPT))
1134 goto twl_interrupt_bail;
1135
1136 handled = 1;
1137
1138
1139 if (test_bit(TW_IN_RESET, &tw_dev->flags))
1140 goto twl_interrupt_bail;
1141
1142
1143 if (reg & TWL_HISTATUS_ATTENTION_INTERRUPT) {
1144 if (twl_handle_attention_interrupt(tw_dev)) {
1145 TWL_MASK_INTERRUPTS(tw_dev);
1146 goto twl_interrupt_bail;
1147 }
1148 }
1149
1150
1151 while (reg & TWL_HISTATUS_RESPONSE_INTERRUPT) {
1152 if (sizeof(dma_addr_t) > 4) {
1153 regh = readl(TWL_HOBQPH_REG_ADDR(tw_dev));
1154 regl = readl(TWL_HOBQPL_REG_ADDR(tw_dev));
1155 mfa = ((u64)regh << 32) | regl;
1156 } else
1157 mfa = readl(TWL_HOBQPL_REG_ADDR(tw_dev));
1158
1159 error = 0;
1160 response = (u32)mfa;
1161
1162
1163 if (!TW_NOTMFA_OUT(response)) {
1164 for (i=0;i<TW_Q_LENGTH;i++) {
1165 if (tw_dev->sense_buffer_phys[i] == mfa) {
1166 request_id = le16_to_cpu(tw_dev->sense_buffer_virt[i]->header_desc.request_id);
1167 if (tw_dev->srb[request_id] != NULL)
1168 error = twl_fill_sense(tw_dev, i, request_id, 1, 1);
1169 else {
1170
1171 if (request_id != tw_dev->chrdev_request_id)
1172 error = twl_fill_sense(tw_dev, i, request_id, 0, 1);
1173 else
1174 memcpy(tw_dev->command_packet_virt[request_id], tw_dev->sense_buffer_virt[i], sizeof(TW_Command_Apache_Header));
1175 }
1176
1177
1178 writel((u32)((u64)tw_dev->sense_buffer_phys[i] >> 32), TWL_HOBQPH_REG_ADDR(tw_dev));
1179 writel((u32)tw_dev->sense_buffer_phys[i], TWL_HOBQPL_REG_ADDR(tw_dev));
1180 break;
1181 }
1182 }
1183 } else
1184 request_id = TW_RESID_OUT(response);
1185
1186 full_command_packet = tw_dev->command_packet_virt[request_id];
1187
1188
1189 if (tw_dev->state[request_id] != TW_S_POSTED) {
1190 if (tw_dev->srb[request_id] != NULL) {
1191 TW_PRINTK(tw_dev->host, TW_DRIVER, 0xe, "Received a request id that wasn't posted");
1192 TWL_MASK_INTERRUPTS(tw_dev);
1193 goto twl_interrupt_bail;
1194 }
1195 }
1196
1197
1198 if (tw_dev->srb[request_id] == NULL) {
1199 if (request_id != tw_dev->chrdev_request_id) {
1200 if (twl_aen_complete(tw_dev, request_id))
1201 TW_PRINTK(tw_dev->host, TW_DRIVER, 0xf, "Error completing AEN during attention interrupt");
1202 } else {
1203 tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE;
1204 wake_up(&tw_dev->ioctl_wqueue);
1205 }
1206 } else {
1207 cmd = tw_dev->srb[request_id];
1208
1209 if (!error)
1210 cmd->result = (DID_OK << 16);
1211
1212
1213 if ((scsi_sg_count(cmd) <= 1) && (full_command_packet->command.newcommand.status == 0)) {
1214 if (full_command_packet->command.newcommand.sg_list[0].length < scsi_bufflen(tw_dev->srb[request_id]))
1215 scsi_set_resid(cmd, scsi_bufflen(cmd) - full_command_packet->command.newcommand.sg_list[0].length);
1216 }
1217
1218
1219 scsi_dma_unmap(cmd);
1220 cmd->scsi_done(cmd);
1221 tw_dev->state[request_id] = TW_S_COMPLETED;
1222 twl_free_request_id(tw_dev, request_id);
1223 tw_dev->posted_request_count--;
1224 }
1225
1226
1227 reg = readl(TWL_HISTAT_REG_ADDR(tw_dev));
1228 }
1229
1230twl_interrupt_bail:
1231 spin_unlock(tw_dev->host->host_lock);
1232 return IRQ_RETVAL(handled);
1233}
1234
1235
1236static int twl_poll_register(TW_Device_Extension *tw_dev, void *reg, u32 value, u32 result, int seconds)
1237{
1238 unsigned long before;
1239 int retval = 1;
1240 u32 reg_value;
1241
1242 reg_value = readl(reg);
1243 before = jiffies;
1244
1245 while ((reg_value & value) != result) {
1246 reg_value = readl(reg);
1247 if (time_after(jiffies, before + HZ * seconds))
1248 goto out;
1249 msleep(50);
1250 }
1251 retval = 0;
1252out:
1253 return retval;
1254}
1255
1256
1257static int twl_reset_sequence(TW_Device_Extension *tw_dev, int soft_reset)
1258{
1259 int retval = 1;
1260 int i = 0;
1261 u32 status = 0;
1262 unsigned short fw_on_ctlr_srl = 0, fw_on_ctlr_arch_id = 0;
1263 unsigned short fw_on_ctlr_branch = 0, fw_on_ctlr_build = 0;
1264 u32 init_connect_result = 0;
1265 int tries = 0;
1266 int do_soft_reset = soft_reset;
1267
1268 while (tries < TW_MAX_RESET_TRIES) {
1269
1270 if (do_soft_reset) {
1271 TWL_SOFT_RESET(tw_dev);
1272
1273
1274 if (twl_poll_register(tw_dev, TWL_SCRPD3_REG_ADDR(tw_dev), TWL_CONTROLLER_READY, 0x0, 30)) {
1275 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x10, "Controller never went non-ready during reset sequence");
1276 tries++;
1277 continue;
1278 }
1279 if (twl_poll_register(tw_dev, TWL_SCRPD3_REG_ADDR(tw_dev), TWL_CONTROLLER_READY, TWL_CONTROLLER_READY, 60)) {
1280 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x11, "Controller not ready during reset sequence");
1281 tries++;
1282 continue;
1283 }
1284 }
1285
1286
1287 if (twl_initconnection(tw_dev, TW_INIT_MESSAGE_CREDITS,
1288 TW_EXTENDED_INIT_CONNECT, TW_CURRENT_DRIVER_SRL,
1289 TW_9750_ARCH_ID, TW_CURRENT_DRIVER_BRANCH,
1290 TW_CURRENT_DRIVER_BUILD, &fw_on_ctlr_srl,
1291 &fw_on_ctlr_arch_id, &fw_on_ctlr_branch,
1292 &fw_on_ctlr_build, &init_connect_result)) {
1293 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x12, "Initconnection failed while checking SRL");
1294 do_soft_reset = 1;
1295 tries++;
1296 continue;
1297 }
1298
1299
1300 while (i < TW_Q_LENGTH) {
1301 writel((u32)((u64)tw_dev->sense_buffer_phys[i] >> 32), TWL_HOBQPH_REG_ADDR(tw_dev));
1302 writel((u32)tw_dev->sense_buffer_phys[i], TWL_HOBQPL_REG_ADDR(tw_dev));
1303
1304
1305 status = readl(TWL_STATUS_REG_ADDR(tw_dev));
1306 if (!(status & TWL_STATUS_OVERRUN_SUBMIT))
1307 i++;
1308 }
1309
1310
1311 status = readl(TWL_STATUS_REG_ADDR(tw_dev));
1312 if (status) {
1313 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x13, "Bad controller status after loading sense buffers");
1314 do_soft_reset = 1;
1315 tries++;
1316 continue;
1317 }
1318
1319
1320 if (twl_aen_drain_queue(tw_dev, soft_reset)) {
1321 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x14, "AEN drain failed during reset sequence");
1322 do_soft_reset = 1;
1323 tries++;
1324 continue;
1325 }
1326
1327
1328 strncpy(tw_dev->tw_compat_info.driver_version, TW_DRIVER_VERSION, strlen(TW_DRIVER_VERSION));
1329 tw_dev->tw_compat_info.driver_srl_high = TW_CURRENT_DRIVER_SRL;
1330 tw_dev->tw_compat_info.driver_branch_high = TW_CURRENT_DRIVER_BRANCH;
1331 tw_dev->tw_compat_info.driver_build_high = TW_CURRENT_DRIVER_BUILD;
1332 tw_dev->tw_compat_info.driver_srl_low = TW_BASE_FW_SRL;
1333 tw_dev->tw_compat_info.driver_branch_low = TW_BASE_FW_BRANCH;
1334 tw_dev->tw_compat_info.driver_build_low = TW_BASE_FW_BUILD;
1335 tw_dev->tw_compat_info.fw_on_ctlr_srl = fw_on_ctlr_srl;
1336 tw_dev->tw_compat_info.fw_on_ctlr_branch = fw_on_ctlr_branch;
1337 tw_dev->tw_compat_info.fw_on_ctlr_build = fw_on_ctlr_build;
1338
1339
1340 retval = 0;
1341 goto out;
1342 }
1343out:
1344 return retval;
1345}
1346
1347
1348static int twl_reset_device_extension(TW_Device_Extension *tw_dev, int ioctl_reset)
1349{
1350 int i = 0, retval = 1;
1351 unsigned long flags = 0;
1352
1353
1354 if (ioctl_reset)
1355 scsi_block_requests(tw_dev->host);
1356
1357 set_bit(TW_IN_RESET, &tw_dev->flags);
1358 TWL_MASK_INTERRUPTS(tw_dev);
1359 TWL_CLEAR_DB_INTERRUPT(tw_dev);
1360
1361 spin_lock_irqsave(tw_dev->host->host_lock, flags);
1362
1363
1364 for (i = 0; i < TW_Q_LENGTH; i++) {
1365 if ((tw_dev->state[i] != TW_S_FINISHED) &&
1366 (tw_dev->state[i] != TW_S_INITIAL) &&
1367 (tw_dev->state[i] != TW_S_COMPLETED)) {
1368 struct scsi_cmnd *cmd = tw_dev->srb[i];
1369
1370 if (cmd) {
1371 cmd->result = (DID_RESET << 16);
1372 scsi_dma_unmap(cmd);
1373 cmd->scsi_done(cmd);
1374 }
1375 }
1376 }
1377
1378
1379 for (i = 0; i < TW_Q_LENGTH; i++) {
1380 tw_dev->free_queue[i] = i;
1381 tw_dev->state[i] = TW_S_INITIAL;
1382 }
1383 tw_dev->free_head = TW_Q_START;
1384 tw_dev->free_tail = TW_Q_START;
1385 tw_dev->posted_request_count = 0;
1386
1387 spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
1388
1389 if (twl_reset_sequence(tw_dev, 1))
1390 goto out;
1391
1392 TWL_UNMASK_INTERRUPTS(tw_dev);
1393
1394 clear_bit(TW_IN_RESET, &tw_dev->flags);
1395 tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE;
1396
1397 retval = 0;
1398out:
1399 if (ioctl_reset)
1400 scsi_unblock_requests(tw_dev->host);
1401 return retval;
1402}
1403
1404
1405static int twl_scsi_biosparam(struct scsi_device *sdev, struct block_device *bdev, sector_t capacity, int geom[])
1406{
1407 int heads, sectors;
1408 TW_Device_Extension *tw_dev;
1409
1410 tw_dev = (TW_Device_Extension *)sdev->host->hostdata;
1411
1412 if (capacity >= 0x200000) {
1413 heads = 255;
1414 sectors = 63;
1415 } else {
1416 heads = 64;
1417 sectors = 32;
1418 }
1419
1420 geom[0] = heads;
1421 geom[1] = sectors;
1422 geom[2] = sector_div(capacity, heads * sectors);
1423
1424 return 0;
1425}
1426
1427
1428static int twl_scsi_eh_reset(struct scsi_cmnd *SCpnt)
1429{
1430 TW_Device_Extension *tw_dev = NULL;
1431 int retval = FAILED;
1432
1433 tw_dev = (TW_Device_Extension *)SCpnt->device->host->hostdata;
1434
1435 tw_dev->num_resets++;
1436
1437 sdev_printk(KERN_WARNING, SCpnt->device,
1438 "WARNING: (0x%02X:0x%04X): Command (0x%x) timed out, resetting card.\n",
1439 TW_DRIVER, 0x2c, SCpnt->cmnd[0]);
1440
1441
1442 mutex_lock(&tw_dev->ioctl_lock);
1443
1444
1445 if (twl_reset_device_extension(tw_dev, 0)) {
1446 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x15, "Controller reset failed during scsi host reset");
1447 goto out;
1448 }
1449
1450 retval = SUCCESS;
1451out:
1452 mutex_unlock(&tw_dev->ioctl_lock);
1453 return retval;
1454}
1455
1456
1457static int twl_scsi_queue_lck(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
1458{
1459 int request_id, retval;
1460 TW_Device_Extension *tw_dev = (TW_Device_Extension *)SCpnt->device->host->hostdata;
1461
1462
1463 if (test_bit(TW_IN_RESET, &tw_dev->flags)) {
1464 retval = SCSI_MLQUEUE_HOST_BUSY;
1465 goto out;
1466 }
1467
1468
1469 SCpnt->scsi_done = done;
1470
1471
1472 twl_get_request_id(tw_dev, &request_id);
1473
1474
1475 tw_dev->srb[request_id] = SCpnt;
1476
1477 retval = twl_scsiop_execute_scsi(tw_dev, request_id, NULL, 0, NULL);
1478 if (retval) {
1479 tw_dev->state[request_id] = TW_S_COMPLETED;
1480 twl_free_request_id(tw_dev, request_id);
1481 SCpnt->result = (DID_ERROR << 16);
1482 done(SCpnt);
1483 retval = 0;
1484 }
1485out:
1486 return retval;
1487}
1488
1489static DEF_SCSI_QCMD(twl_scsi_queue)
1490
1491
1492static void __twl_shutdown(TW_Device_Extension *tw_dev)
1493{
1494
1495 TWL_MASK_INTERRUPTS(tw_dev);
1496
1497
1498 free_irq(tw_dev->tw_pci_dev->irq, tw_dev);
1499
1500 printk(KERN_WARNING "3w-sas: Shutting down host %d.\n", tw_dev->host->host_no);
1501
1502
1503 if (twl_initconnection(tw_dev, 1, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL)) {
1504 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x16, "Connection shutdown failed");
1505 } else {
1506 printk(KERN_WARNING "3w-sas: Shutdown complete.\n");
1507 }
1508
1509
1510 TWL_CLEAR_DB_INTERRUPT(tw_dev);
1511}
1512
1513
1514static void twl_shutdown(struct pci_dev *pdev)
1515{
1516 struct Scsi_Host *host = pci_get_drvdata(pdev);
1517 TW_Device_Extension *tw_dev;
1518
1519 if (!host)
1520 return;
1521
1522 tw_dev = (TW_Device_Extension *)host->hostdata;
1523
1524 if (tw_dev->online)
1525 __twl_shutdown(tw_dev);
1526}
1527
1528
1529static int twl_slave_configure(struct scsi_device *sdev)
1530{
1531
1532 blk_queue_rq_timeout(sdev->request_queue, 60 * HZ);
1533
1534 return 0;
1535}
1536
1537
1538static struct scsi_host_template driver_template = {
1539 .module = THIS_MODULE,
1540 .name = "3w-sas",
1541 .queuecommand = twl_scsi_queue,
1542 .eh_host_reset_handler = twl_scsi_eh_reset,
1543 .bios_param = twl_scsi_biosparam,
1544 .change_queue_depth = scsi_change_queue_depth,
1545 .can_queue = TW_Q_LENGTH-2,
1546 .slave_configure = twl_slave_configure,
1547 .this_id = -1,
1548 .sg_tablesize = TW_LIBERATOR_MAX_SGL_LENGTH,
1549 .max_sectors = TW_MAX_SECTORS,
1550 .cmd_per_lun = TW_MAX_CMDS_PER_LUN,
1551 .use_clustering = ENABLE_CLUSTERING,
1552 .shost_attrs = twl_host_attrs,
1553 .emulated = 1,
1554 .no_write_same = 1,
1555};
1556
1557
1558static int twl_probe(struct pci_dev *pdev, const struct pci_device_id *dev_id)
1559{
1560 struct Scsi_Host *host = NULL;
1561 TW_Device_Extension *tw_dev;
1562 int retval = -ENODEV;
1563 int *ptr_phycount, phycount=0;
1564
1565 retval = pci_enable_device(pdev);
1566 if (retval) {
1567 TW_PRINTK(host, TW_DRIVER, 0x17, "Failed to enable pci device");
1568 goto out_disable_device;
1569 }
1570
1571 pci_set_master(pdev);
1572 pci_try_set_mwi(pdev);
1573
1574 if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64))
1575 || pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)))
1576 if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32))
1577 || pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) {
1578 TW_PRINTK(host, TW_DRIVER, 0x18, "Failed to set dma mask");
1579 retval = -ENODEV;
1580 goto out_disable_device;
1581 }
1582
1583 host = scsi_host_alloc(&driver_template, sizeof(TW_Device_Extension));
1584 if (!host) {
1585 TW_PRINTK(host, TW_DRIVER, 0x19, "Failed to allocate memory for device extension");
1586 retval = -ENOMEM;
1587 goto out_disable_device;
1588 }
1589 tw_dev = shost_priv(host);
1590
1591
1592 tw_dev->host = host;
1593 tw_dev->tw_pci_dev = pdev;
1594
1595 if (twl_initialize_device_extension(tw_dev)) {
1596 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1a, "Failed to initialize device extension");
1597 goto out_free_device_extension;
1598 }
1599
1600
1601 retval = pci_request_regions(pdev, "3w-sas");
1602 if (retval) {
1603 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1b, "Failed to get mem region");
1604 goto out_free_device_extension;
1605 }
1606
1607
1608 tw_dev->base_addr = pci_iomap(pdev, 1, 0);
1609 if (!tw_dev->base_addr) {
1610 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1c, "Failed to ioremap");
1611 goto out_release_mem_region;
1612 }
1613
1614
1615 TWL_MASK_INTERRUPTS(tw_dev);
1616
1617
1618 if (twl_reset_sequence(tw_dev, 0)) {
1619 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1d, "Controller reset failed during probe");
1620 goto out_iounmap;
1621 }
1622
1623
1624 host->max_id = TW_MAX_UNITS;
1625 host->max_cmd_len = TW_MAX_CDB_LEN;
1626 host->max_lun = TW_MAX_LUNS;
1627 host->max_channel = 0;
1628
1629
1630 retval = scsi_add_host(host, &pdev->dev);
1631 if (retval) {
1632 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1e, "scsi add host failed");
1633 goto out_iounmap;
1634 }
1635
1636 pci_set_drvdata(pdev, host);
1637
1638 printk(KERN_WARNING "3w-sas: scsi%d: Found an LSI 3ware %s Controller at 0x%llx, IRQ: %d.\n",
1639 host->host_no,
1640 (char *)twl_get_param(tw_dev, 1, TW_VERSION_TABLE,
1641 TW_PARAM_MODEL, TW_PARAM_MODEL_LENGTH),
1642 (u64)pci_resource_start(pdev, 1), pdev->irq);
1643
1644 ptr_phycount = twl_get_param(tw_dev, 2, TW_PARAM_PHY_SUMMARY_TABLE,
1645 TW_PARAM_PHYCOUNT, TW_PARAM_PHYCOUNT_LENGTH);
1646 if (ptr_phycount)
1647 phycount = le32_to_cpu(*(int *)ptr_phycount);
1648
1649 printk(KERN_WARNING "3w-sas: scsi%d: Firmware %s, BIOS %s, Phys: %d.\n",
1650 host->host_no,
1651 (char *)twl_get_param(tw_dev, 1, TW_VERSION_TABLE,
1652 TW_PARAM_FWVER, TW_PARAM_FWVER_LENGTH),
1653 (char *)twl_get_param(tw_dev, 2, TW_VERSION_TABLE,
1654 TW_PARAM_BIOSVER, TW_PARAM_BIOSVER_LENGTH),
1655 phycount);
1656
1657
1658 if (use_msi && !pci_enable_msi(pdev))
1659 set_bit(TW_USING_MSI, &tw_dev->flags);
1660
1661
1662 retval = request_irq(pdev->irq, twl_interrupt, IRQF_SHARED, "3w-sas", tw_dev);
1663 if (retval) {
1664 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1f, "Error requesting IRQ");
1665 goto out_remove_host;
1666 }
1667
1668 twl_device_extension_list[twl_device_extension_count] = tw_dev;
1669 twl_device_extension_count++;
1670
1671
1672 TWL_UNMASK_INTERRUPTS(tw_dev);
1673
1674
1675 scsi_scan_host(host);
1676
1677
1678 if (sysfs_create_bin_file(&host->shost_dev.kobj, &twl_sysfs_aen_read_attr))
1679 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x20, "Failed to create sysfs binary file: 3ware_aen_read");
1680 if (sysfs_create_bin_file(&host->shost_dev.kobj, &twl_sysfs_compat_info_attr))
1681 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x21, "Failed to create sysfs binary file: 3ware_compat_info");
1682
1683 if (twl_major == -1) {
1684 if ((twl_major = register_chrdev (0, "twl", &twl_fops)) < 0)
1685 TW_PRINTK(host, TW_DRIVER, 0x22, "Failed to register character device");
1686 }
1687 tw_dev->online = 1;
1688 return 0;
1689
1690out_remove_host:
1691 if (test_bit(TW_USING_MSI, &tw_dev->flags))
1692 pci_disable_msi(pdev);
1693 scsi_remove_host(host);
1694out_iounmap:
1695 iounmap(tw_dev->base_addr);
1696out_release_mem_region:
1697 pci_release_regions(pdev);
1698out_free_device_extension:
1699 twl_free_device_extension(tw_dev);
1700 scsi_host_put(host);
1701out_disable_device:
1702 pci_disable_device(pdev);
1703
1704 return retval;
1705}
1706
1707
1708static void twl_remove(struct pci_dev *pdev)
1709{
1710 struct Scsi_Host *host = pci_get_drvdata(pdev);
1711 TW_Device_Extension *tw_dev;
1712
1713 if (!host)
1714 return;
1715
1716 tw_dev = (TW_Device_Extension *)host->hostdata;
1717
1718 if (!tw_dev->online)
1719 return;
1720
1721
1722 sysfs_remove_bin_file(&host->shost_dev.kobj, &twl_sysfs_aen_read_attr);
1723 sysfs_remove_bin_file(&host->shost_dev.kobj, &twl_sysfs_compat_info_attr);
1724
1725 scsi_remove_host(tw_dev->host);
1726
1727
1728 if (twl_major >= 0) {
1729 unregister_chrdev(twl_major, "twl");
1730 twl_major = -1;
1731 }
1732
1733
1734 __twl_shutdown(tw_dev);
1735
1736
1737 if (test_bit(TW_USING_MSI, &tw_dev->flags))
1738 pci_disable_msi(pdev);
1739
1740
1741 iounmap(tw_dev->base_addr);
1742
1743
1744 pci_release_regions(pdev);
1745
1746
1747 twl_free_device_extension(tw_dev);
1748
1749 scsi_host_put(tw_dev->host);
1750 pci_disable_device(pdev);
1751 twl_device_extension_count--;
1752}
1753
1754#ifdef CONFIG_PM
1755
1756static int twl_suspend(struct pci_dev *pdev, pm_message_t state)
1757{
1758 struct Scsi_Host *host = pci_get_drvdata(pdev);
1759 TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata;
1760
1761 printk(KERN_WARNING "3w-sas: Suspending host %d.\n", tw_dev->host->host_no);
1762
1763 TWL_MASK_INTERRUPTS(tw_dev);
1764
1765 free_irq(tw_dev->tw_pci_dev->irq, tw_dev);
1766
1767
1768 if (twl_initconnection(tw_dev, 1, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL)) {
1769 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x23, "Connection shutdown failed during suspend");
1770 } else {
1771 printk(KERN_WARNING "3w-sas: Suspend complete.\n");
1772 }
1773
1774
1775 TWL_CLEAR_DB_INTERRUPT(tw_dev);
1776
1777 pci_save_state(pdev);
1778 pci_disable_device(pdev);
1779 pci_set_power_state(pdev, pci_choose_state(pdev, state));
1780
1781 return 0;
1782}
1783
1784
1785static int twl_resume(struct pci_dev *pdev)
1786{
1787 int retval = 0;
1788 struct Scsi_Host *host = pci_get_drvdata(pdev);
1789 TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata;
1790
1791 printk(KERN_WARNING "3w-sas: Resuming host %d.\n", tw_dev->host->host_no);
1792 pci_set_power_state(pdev, PCI_D0);
1793 pci_enable_wake(pdev, PCI_D0, 0);
1794 pci_restore_state(pdev);
1795
1796 retval = pci_enable_device(pdev);
1797 if (retval) {
1798 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x24, "Enable device failed during resume");
1799 return retval;
1800 }
1801
1802 pci_set_master(pdev);
1803 pci_try_set_mwi(pdev);
1804
1805 if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64))
1806 || pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)))
1807 if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32))
1808 || pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) {
1809 TW_PRINTK(host, TW_DRIVER, 0x25, "Failed to set dma mask during resume");
1810 retval = -ENODEV;
1811 goto out_disable_device;
1812 }
1813
1814
1815 if (twl_reset_sequence(tw_dev, 0)) {
1816 retval = -ENODEV;
1817 goto out_disable_device;
1818 }
1819
1820
1821 retval = request_irq(pdev->irq, twl_interrupt, IRQF_SHARED, "3w-sas", tw_dev);
1822 if (retval) {
1823 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x26, "Error requesting IRQ during resume");
1824 retval = -ENODEV;
1825 goto out_disable_device;
1826 }
1827
1828
1829 if (test_bit(TW_USING_MSI, &tw_dev->flags))
1830 pci_enable_msi(pdev);
1831
1832
1833 TWL_UNMASK_INTERRUPTS(tw_dev);
1834
1835 printk(KERN_WARNING "3w-sas: Resume complete.\n");
1836 return 0;
1837
1838out_disable_device:
1839 scsi_remove_host(host);
1840 pci_disable_device(pdev);
1841
1842 return retval;
1843}
1844#endif
1845
1846
1847static struct pci_device_id twl_pci_tbl[] = {
1848 { PCI_VDEVICE(3WARE, PCI_DEVICE_ID_3WARE_9750) },
1849 { }
1850};
1851MODULE_DEVICE_TABLE(pci, twl_pci_tbl);
1852
1853
1854static struct pci_driver twl_driver = {
1855 .name = "3w-sas",
1856 .id_table = twl_pci_tbl,
1857 .probe = twl_probe,
1858 .remove = twl_remove,
1859#ifdef CONFIG_PM
1860 .suspend = twl_suspend,
1861 .resume = twl_resume,
1862#endif
1863 .shutdown = twl_shutdown
1864};
1865
1866
1867static int __init twl_init(void)
1868{
1869 printk(KERN_INFO "LSI 3ware SAS/SATA-RAID Controller device driver for Linux v%s.\n", TW_DRIVER_VERSION);
1870
1871 return pci_register_driver(&twl_driver);
1872}
1873
1874
1875static void __exit twl_exit(void)
1876{
1877 pci_unregister_driver(&twl_driver);
1878}
1879
1880module_init(twl_init);
1881module_exit(twl_exit);
1882
1883