0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053 #include <linux/module.h>
0054 #include <linux/reboot.h>
0055 #include <linux/spinlock.h>
0056 #include <linux/interrupt.h>
0057 #include <linux/moduleparam.h>
0058 #include <linux/errno.h>
0059 #include <linux/types.h>
0060 #include <linux/delay.h>
0061 #include <linux/pci.h>
0062 #include <linux/time.h>
0063 #include <linux/mutex.h>
0064 #include <linux/slab.h>
0065 #include <asm/io.h>
0066 #include <asm/irq.h>
0067 #include <linux/uaccess.h>
0068 #include <scsi/scsi.h>
0069 #include <scsi/scsi_host.h>
0070 #include <scsi/scsi_tcq.h>
0071 #include <scsi/scsi_cmnd.h>
0072 #include "3w-sas.h"
0073
0074
0075 #define TW_DRIVER_VERSION "3.26.02.000"
0076 static DEFINE_MUTEX(twl_chrdev_mutex);
0077 static TW_Device_Extension *twl_device_extension_list[TW_MAX_SLOT];
0078 static unsigned int twl_device_extension_count;
0079 static int twl_major = -1;
0080 extern struct timezone sys_tz;
0081
0082
0083 MODULE_AUTHOR ("LSI");
0084 MODULE_DESCRIPTION ("LSI 3ware SAS/SATA-RAID Linux Driver");
0085 MODULE_LICENSE("GPL");
0086 MODULE_VERSION(TW_DRIVER_VERSION);
0087
0088 static int use_msi;
0089 module_param(use_msi, int, S_IRUGO);
0090 MODULE_PARM_DESC(use_msi, "Use Message Signaled Interrupts. Default: 0");
0091
0092
0093 static int twl_reset_device_extension(TW_Device_Extension *tw_dev, int ioctl_reset);
0094
0095
0096
0097
0098 static ssize_t twl_sysfs_aen_read(struct file *filp, struct kobject *kobj,
0099 struct bin_attribute *bin_attr,
0100 char *outbuf, loff_t offset, size_t count)
0101 {
0102 struct device *dev = container_of(kobj, struct device, kobj);
0103 struct Scsi_Host *shost = class_to_shost(dev);
0104 TW_Device_Extension *tw_dev = (TW_Device_Extension *)shost->hostdata;
0105 unsigned long flags = 0;
0106 ssize_t ret;
0107
0108 if (!capable(CAP_SYS_ADMIN))
0109 return -EACCES;
0110
0111 spin_lock_irqsave(tw_dev->host->host_lock, flags);
0112 ret = memory_read_from_buffer(outbuf, count, &offset, tw_dev->event_queue[0], sizeof(TW_Event) * TW_Q_LENGTH);
0113 spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
0114
0115 return ret;
0116 }
0117
0118
0119 static struct bin_attribute twl_sysfs_aen_read_attr = {
0120 .attr = {
0121 .name = "3ware_aen_read",
0122 .mode = S_IRUSR,
0123 },
0124 .size = 0,
0125 .read = twl_sysfs_aen_read
0126 };
0127
0128
0129 static ssize_t twl_sysfs_compat_info(struct file *filp, struct kobject *kobj,
0130 struct bin_attribute *bin_attr,
0131 char *outbuf, loff_t offset, size_t count)
0132 {
0133 struct device *dev = container_of(kobj, struct device, kobj);
0134 struct Scsi_Host *shost = class_to_shost(dev);
0135 TW_Device_Extension *tw_dev = (TW_Device_Extension *)shost->hostdata;
0136 unsigned long flags = 0;
0137 ssize_t ret;
0138
0139 if (!capable(CAP_SYS_ADMIN))
0140 return -EACCES;
0141
0142 spin_lock_irqsave(tw_dev->host->host_lock, flags);
0143 ret = memory_read_from_buffer(outbuf, count, &offset, &tw_dev->tw_compat_info, sizeof(TW_Compatibility_Info));
0144 spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
0145
0146 return ret;
0147 }
0148
0149
0150 static struct bin_attribute twl_sysfs_compat_info_attr = {
0151 .attr = {
0152 .name = "3ware_compat_info",
0153 .mode = S_IRUSR,
0154 },
0155 .size = 0,
0156 .read = twl_sysfs_compat_info
0157 };
0158
0159
0160 static ssize_t twl_show_stats(struct device *dev,
0161 struct device_attribute *attr, char *buf)
0162 {
0163 struct Scsi_Host *host = class_to_shost(dev);
0164 TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata;
0165 unsigned long flags = 0;
0166 ssize_t len;
0167
0168 spin_lock_irqsave(tw_dev->host->host_lock, flags);
0169 len = snprintf(buf, PAGE_SIZE, "3w-sas Driver version: %s\n"
0170 "Current commands posted: %4d\n"
0171 "Max commands posted: %4d\n"
0172 "Last sgl length: %4d\n"
0173 "Max sgl length: %4d\n"
0174 "Last sector count: %4d\n"
0175 "Max sector count: %4d\n"
0176 "SCSI Host Resets: %4d\n"
0177 "AEN's: %4d\n",
0178 TW_DRIVER_VERSION,
0179 tw_dev->posted_request_count,
0180 tw_dev->max_posted_request_count,
0181 tw_dev->sgl_entries,
0182 tw_dev->max_sgl_entries,
0183 tw_dev->sector_count,
0184 tw_dev->max_sector_count,
0185 tw_dev->num_resets,
0186 tw_dev->aen_count);
0187 spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
0188 return len;
0189 }
0190
0191
0192 static struct device_attribute twl_host_stats_attr = {
0193 .attr = {
0194 .name = "3ware_stats",
0195 .mode = S_IRUGO,
0196 },
0197 .show = twl_show_stats
0198 };
0199
0200
0201 static struct attribute *twl_host_attrs[] = {
0202 &twl_host_stats_attr.attr,
0203 NULL,
0204 };
0205
0206 ATTRIBUTE_GROUPS(twl_host);
0207
0208
0209 static char *twl_aen_severity_lookup(unsigned char severity_code)
0210 {
0211 char *retval = NULL;
0212
0213 if ((severity_code < (unsigned char) TW_AEN_SEVERITY_ERROR) ||
0214 (severity_code > (unsigned char) TW_AEN_SEVERITY_DEBUG))
0215 goto out;
0216
0217 retval = twl_aen_severity_table[severity_code];
0218 out:
0219 return retval;
0220 }
0221
0222
0223 static void twl_aen_queue_event(TW_Device_Extension *tw_dev, TW_Command_Apache_Header *header)
0224 {
0225 u32 local_time;
0226 TW_Event *event;
0227 unsigned short aen;
0228 char host[16];
0229 char *error_str;
0230
0231 tw_dev->aen_count++;
0232
0233
0234 event = tw_dev->event_queue[tw_dev->error_index];
0235
0236 host[0] = '\0';
0237 if (tw_dev->host)
0238 sprintf(host, " scsi%d:", tw_dev->host->host_no);
0239
0240 aen = le16_to_cpu(header->status_block.error);
0241 memset(event, 0, sizeof(TW_Event));
0242
0243 event->severity = TW_SEV_OUT(header->status_block.severity__reserved);
0244
0245 local_time = (u32)(ktime_get_real_seconds() - (sys_tz.tz_minuteswest * 60));
0246 event->time_stamp_sec = local_time;
0247 event->aen_code = aen;
0248 event->retrieved = TW_AEN_NOT_RETRIEVED;
0249 event->sequence_id = tw_dev->error_sequence_id;
0250 tw_dev->error_sequence_id++;
0251
0252
0253 error_str = &(header->err_specific_desc[strlen(header->err_specific_desc)+1]);
0254
0255 header->err_specific_desc[sizeof(header->err_specific_desc) - 1] = '\0';
0256 event->parameter_len = strlen(header->err_specific_desc);
0257 memcpy(event->parameter_data, header->err_specific_desc, event->parameter_len + 1 + strlen(error_str));
0258 if (event->severity != TW_AEN_SEVERITY_DEBUG)
0259 printk(KERN_WARNING "3w-sas:%s AEN: %s (0x%02X:0x%04X): %s:%s.\n",
0260 host,
0261 twl_aen_severity_lookup(TW_SEV_OUT(header->status_block.severity__reserved)),
0262 TW_MESSAGE_SOURCE_CONTROLLER_EVENT, aen, error_str,
0263 header->err_specific_desc);
0264 else
0265 tw_dev->aen_count--;
0266
0267 tw_dev->error_index = (tw_dev->error_index + 1 ) % TW_Q_LENGTH;
0268 }
0269
0270
0271 static int twl_post_command_packet(TW_Device_Extension *tw_dev, int request_id)
0272 {
0273 dma_addr_t command_que_value;
0274
0275 command_que_value = tw_dev->command_packet_phys[request_id];
0276 command_que_value += TW_COMMAND_OFFSET;
0277
0278
0279 writel((u32)((u64)command_que_value >> 32), TWL_HIBQPH_REG_ADDR(tw_dev));
0280
0281 writel((u32)(command_que_value | TWL_PULL_MODE), TWL_HIBQPL_REG_ADDR(tw_dev));
0282
0283 tw_dev->state[request_id] = TW_S_POSTED;
0284 tw_dev->posted_request_count++;
0285 if (tw_dev->posted_request_count > tw_dev->max_posted_request_count)
0286 tw_dev->max_posted_request_count = tw_dev->posted_request_count;
0287
0288 return 0;
0289 }
0290
0291
0292 static int twl_scsiop_execute_scsi(TW_Device_Extension *tw_dev, int request_id,
0293 unsigned char *cdb, int use_sg,
0294 TW_SG_Entry_ISO *sglistarg)
0295 {
0296 TW_Command_Full *full_command_packet;
0297 TW_Command_Apache *command_packet;
0298 int i, sg_count;
0299 struct scsi_cmnd *srb = NULL;
0300 struct scatterlist *sg;
0301 int retval = 1;
0302
0303 if (tw_dev->srb[request_id])
0304 srb = tw_dev->srb[request_id];
0305
0306
0307 full_command_packet = tw_dev->command_packet_virt[request_id];
0308 full_command_packet->header.header_desc.size_header = 128;
0309 full_command_packet->header.status_block.error = 0;
0310 full_command_packet->header.status_block.severity__reserved = 0;
0311
0312 command_packet = &full_command_packet->command.newcommand;
0313 command_packet->status = 0;
0314 command_packet->opcode__reserved = TW_OPRES_IN(0, TW_OP_EXECUTE_SCSI);
0315
0316
0317 if (!cdb)
0318 memcpy(command_packet->cdb, srb->cmnd, TW_MAX_CDB_LEN);
0319 else
0320 memcpy(command_packet->cdb, cdb, TW_MAX_CDB_LEN);
0321
0322 if (srb) {
0323 command_packet->unit = srb->device->id;
0324 command_packet->request_id__lunl =
0325 cpu_to_le16(TW_REQ_LUN_IN(srb->device->lun, request_id));
0326 } else {
0327 command_packet->request_id__lunl =
0328 cpu_to_le16(TW_REQ_LUN_IN(0, request_id));
0329 command_packet->unit = 0;
0330 }
0331
0332 command_packet->sgl_offset = 16;
0333
0334 if (!sglistarg) {
0335
0336 if (scsi_sg_count(srb)) {
0337 sg_count = scsi_dma_map(srb);
0338 if (sg_count <= 0)
0339 goto out;
0340
0341 scsi_for_each_sg(srb, sg, sg_count, i) {
0342 command_packet->sg_list[i].address = TW_CPU_TO_SGL(sg_dma_address(sg));
0343 command_packet->sg_list[i].length = TW_CPU_TO_SGL(sg_dma_len(sg));
0344 }
0345 command_packet->sgl_entries__lunh = cpu_to_le16(TW_REQ_LUN_IN((srb->device->lun >> 4), scsi_sg_count(tw_dev->srb[request_id])));
0346 }
0347 } else {
0348
0349 for (i = 0; i < use_sg; i++) {
0350 command_packet->sg_list[i].address = TW_CPU_TO_SGL(sglistarg[i].address);
0351 command_packet->sg_list[i].length = TW_CPU_TO_SGL(sglistarg[i].length);
0352 }
0353 command_packet->sgl_entries__lunh = cpu_to_le16(TW_REQ_LUN_IN(0, use_sg));
0354 }
0355
0356
0357 if (srb) {
0358 tw_dev->sector_count = scsi_bufflen(srb) / 512;
0359 if (tw_dev->sector_count > tw_dev->max_sector_count)
0360 tw_dev->max_sector_count = tw_dev->sector_count;
0361 tw_dev->sgl_entries = scsi_sg_count(srb);
0362 if (tw_dev->sgl_entries > tw_dev->max_sgl_entries)
0363 tw_dev->max_sgl_entries = tw_dev->sgl_entries;
0364 }
0365
0366
0367 retval = twl_post_command_packet(tw_dev, request_id);
0368
0369 out:
0370 return retval;
0371 }
0372
0373
0374 static int twl_aen_read_queue(TW_Device_Extension *tw_dev, int request_id)
0375 {
0376 unsigned char cdb[TW_MAX_CDB_LEN];
0377 TW_SG_Entry_ISO sglist[1];
0378 TW_Command_Full *full_command_packet;
0379 int retval = 1;
0380
0381 full_command_packet = tw_dev->command_packet_virt[request_id];
0382 memset(full_command_packet, 0, sizeof(TW_Command_Full));
0383
0384
0385 memset(&cdb, 0, TW_MAX_CDB_LEN);
0386 cdb[0] = REQUEST_SENSE;
0387 cdb[4] = TW_ALLOCATION_LENGTH;
0388
0389
0390 memset(&sglist, 0, sizeof(TW_SG_Entry_ISO));
0391 sglist[0].length = TW_SECTOR_SIZE;
0392 sglist[0].address = tw_dev->generic_buffer_phys[request_id];
0393
0394
0395 tw_dev->srb[request_id] = NULL;
0396
0397
0398 if (twl_scsiop_execute_scsi(tw_dev, request_id, cdb, 1, sglist)) {
0399 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x2, "Post failed while reading AEN queue");
0400 goto out;
0401 }
0402 retval = 0;
0403 out:
0404 return retval;
0405 }
0406
0407
0408 static void twl_aen_sync_time(TW_Device_Extension *tw_dev, int request_id)
0409 {
0410 u32 schedulertime;
0411 TW_Command_Full *full_command_packet;
0412 TW_Command *command_packet;
0413 TW_Param_Apache *param;
0414 time64_t local_time;
0415
0416
0417 full_command_packet = tw_dev->command_packet_virt[request_id];
0418 memset(full_command_packet, 0, sizeof(TW_Command_Full));
0419 command_packet = &full_command_packet->command.oldcommand;
0420 command_packet->opcode__sgloffset = TW_OPSGL_IN(2, TW_OP_SET_PARAM);
0421 command_packet->request_id = request_id;
0422 command_packet->byte8_offset.param.sgl[0].address = TW_CPU_TO_SGL(tw_dev->generic_buffer_phys[request_id]);
0423 command_packet->byte8_offset.param.sgl[0].length = TW_CPU_TO_SGL(TW_SECTOR_SIZE);
0424 command_packet->size = TW_COMMAND_SIZE;
0425 command_packet->byte6_offset.parameter_count = cpu_to_le16(1);
0426
0427
0428 param = (TW_Param_Apache *)tw_dev->generic_buffer_virt[request_id];
0429 memset(param, 0, TW_SECTOR_SIZE);
0430 param->table_id = cpu_to_le16(TW_TIMEKEEP_TABLE | 0x8000);
0431 param->parameter_id = cpu_to_le16(0x3);
0432 param->parameter_size_bytes = cpu_to_le16(4);
0433
0434
0435
0436 local_time = (ktime_get_real_seconds() - (sys_tz.tz_minuteswest * 60));
0437 div_u64_rem(local_time - (3 * 86400), 604800, &schedulertime);
0438 schedulertime = cpu_to_le32(schedulertime);
0439
0440 memcpy(param->data, &schedulertime, sizeof(u32));
0441
0442
0443 tw_dev->srb[request_id] = NULL;
0444
0445
0446 twl_post_command_packet(tw_dev, request_id);
0447 }
0448
0449
0450 static void twl_get_request_id(TW_Device_Extension *tw_dev, int *request_id)
0451 {
0452 *request_id = tw_dev->free_queue[tw_dev->free_head];
0453 tw_dev->free_head = (tw_dev->free_head + 1) % TW_Q_LENGTH;
0454 tw_dev->state[*request_id] = TW_S_STARTED;
0455 }
0456
0457
0458 static void twl_free_request_id(TW_Device_Extension *tw_dev, int request_id)
0459 {
0460 tw_dev->free_queue[tw_dev->free_tail] = request_id;
0461 tw_dev->state[request_id] = TW_S_FINISHED;
0462 tw_dev->free_tail = (tw_dev->free_tail + 1) % TW_Q_LENGTH;
0463 }
0464
0465
0466 static int twl_aen_complete(TW_Device_Extension *tw_dev, int request_id)
0467 {
0468 TW_Command_Full *full_command_packet;
0469 TW_Command *command_packet;
0470 TW_Command_Apache_Header *header;
0471 unsigned short aen;
0472 int retval = 1;
0473
0474 header = (TW_Command_Apache_Header *)tw_dev->generic_buffer_virt[request_id];
0475 tw_dev->posted_request_count--;
0476 aen = le16_to_cpu(header->status_block.error);
0477 full_command_packet = tw_dev->command_packet_virt[request_id];
0478 command_packet = &full_command_packet->command.oldcommand;
0479
0480
0481 if (TW_OP_OUT(command_packet->opcode__sgloffset) == TW_OP_SET_PARAM) {
0482
0483 if (twl_aen_read_queue(tw_dev, request_id))
0484 goto out2;
0485 else {
0486 retval = 0;
0487 goto out;
0488 }
0489 }
0490
0491 switch (aen) {
0492 case TW_AEN_QUEUE_EMPTY:
0493
0494 break;
0495 case TW_AEN_SYNC_TIME_WITH_HOST:
0496 twl_aen_sync_time(tw_dev, request_id);
0497 retval = 0;
0498 goto out;
0499 default:
0500 twl_aen_queue_event(tw_dev, header);
0501
0502
0503 if (twl_aen_read_queue(tw_dev, request_id))
0504 goto out2;
0505 else {
0506 retval = 0;
0507 goto out;
0508 }
0509 }
0510 retval = 0;
0511 out2:
0512 tw_dev->state[request_id] = TW_S_COMPLETED;
0513 twl_free_request_id(tw_dev, request_id);
0514 clear_bit(TW_IN_ATTENTION_LOOP, &tw_dev->flags);
0515 out:
0516 return retval;
0517 }
0518
0519
0520 static int twl_poll_response(TW_Device_Extension *tw_dev, int request_id, int seconds)
0521 {
0522 unsigned long before;
0523 dma_addr_t mfa;
0524 u32 regh, regl;
0525 u32 response;
0526 int retval = 1;
0527 int found = 0;
0528
0529 before = jiffies;
0530
0531 while (!found) {
0532 if (sizeof(dma_addr_t) > 4) {
0533 regh = readl(TWL_HOBQPH_REG_ADDR(tw_dev));
0534 regl = readl(TWL_HOBQPL_REG_ADDR(tw_dev));
0535 mfa = ((u64)regh << 32) | regl;
0536 } else
0537 mfa = readl(TWL_HOBQPL_REG_ADDR(tw_dev));
0538
0539 response = (u32)mfa;
0540
0541 if (TW_RESID_OUT(response) == request_id)
0542 found = 1;
0543
0544 if (time_after(jiffies, before + HZ * seconds))
0545 goto out;
0546
0547 msleep(50);
0548 }
0549 retval = 0;
0550 out:
0551 return retval;
0552 }
0553
0554
0555 static int twl_aen_drain_queue(TW_Device_Extension *tw_dev, int no_check_reset)
0556 {
0557 int request_id = 0;
0558 unsigned char cdb[TW_MAX_CDB_LEN];
0559 TW_SG_Entry_ISO sglist[1];
0560 int finished = 0, count = 0;
0561 TW_Command_Full *full_command_packet;
0562 TW_Command_Apache_Header *header;
0563 unsigned short aen;
0564 int first_reset = 0, queue = 0, retval = 1;
0565
0566 if (no_check_reset)
0567 first_reset = 0;
0568 else
0569 first_reset = 1;
0570
0571 full_command_packet = tw_dev->command_packet_virt[request_id];
0572 memset(full_command_packet, 0, sizeof(TW_Command_Full));
0573
0574
0575 memset(&cdb, 0, TW_MAX_CDB_LEN);
0576 cdb[0] = REQUEST_SENSE;
0577 cdb[4] = TW_ALLOCATION_LENGTH;
0578
0579
0580 memset(&sglist, 0, sizeof(TW_SG_Entry_ISO));
0581 sglist[0].length = TW_SECTOR_SIZE;
0582 sglist[0].address = tw_dev->generic_buffer_phys[request_id];
0583
0584
0585 tw_dev->srb[request_id] = NULL;
0586
0587 do {
0588
0589 if (twl_scsiop_execute_scsi(tw_dev, request_id, cdb, 1, sglist)) {
0590 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x3, "Error posting request sense");
0591 goto out;
0592 }
0593
0594
0595 if (twl_poll_response(tw_dev, request_id, 30)) {
0596 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x4, "No valid response while draining AEN queue");
0597 tw_dev->posted_request_count--;
0598 goto out;
0599 }
0600
0601 tw_dev->posted_request_count--;
0602 header = (TW_Command_Apache_Header *)tw_dev->generic_buffer_virt[request_id];
0603 aen = le16_to_cpu(header->status_block.error);
0604 queue = 0;
0605 count++;
0606
0607 switch (aen) {
0608 case TW_AEN_QUEUE_EMPTY:
0609 if (first_reset != 1)
0610 goto out;
0611 else
0612 finished = 1;
0613 break;
0614 case TW_AEN_SOFT_RESET:
0615 if (first_reset == 0)
0616 first_reset = 1;
0617 else
0618 queue = 1;
0619 break;
0620 case TW_AEN_SYNC_TIME_WITH_HOST:
0621 break;
0622 default:
0623 queue = 1;
0624 }
0625
0626
0627 if (queue)
0628 twl_aen_queue_event(tw_dev, header);
0629 } while ((finished == 0) && (count < TW_MAX_AEN_DRAIN));
0630
0631 if (count == TW_MAX_AEN_DRAIN)
0632 goto out;
0633
0634 retval = 0;
0635 out:
0636 tw_dev->state[request_id] = TW_S_INITIAL;
0637 return retval;
0638 }
0639
0640
0641 static int twl_allocate_memory(TW_Device_Extension *tw_dev, int size, int which)
0642 {
0643 int i;
0644 dma_addr_t dma_handle;
0645 unsigned long *cpu_addr;
0646 int retval = 1;
0647
0648 cpu_addr = dma_alloc_coherent(&tw_dev->tw_pci_dev->dev,
0649 size * TW_Q_LENGTH, &dma_handle,
0650 GFP_KERNEL);
0651 if (!cpu_addr) {
0652 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x5, "Memory allocation failed");
0653 goto out;
0654 }
0655
0656 for (i = 0; i < TW_Q_LENGTH; i++) {
0657 switch(which) {
0658 case 0:
0659 tw_dev->command_packet_phys[i] = dma_handle+(i*size);
0660 tw_dev->command_packet_virt[i] = (TW_Command_Full *)((unsigned char *)cpu_addr + (i*size));
0661 break;
0662 case 1:
0663 tw_dev->generic_buffer_phys[i] = dma_handle+(i*size);
0664 tw_dev->generic_buffer_virt[i] = (unsigned long *)((unsigned char *)cpu_addr + (i*size));
0665 break;
0666 case 2:
0667 tw_dev->sense_buffer_phys[i] = dma_handle+(i*size);
0668 tw_dev->sense_buffer_virt[i] = (TW_Command_Apache_Header *)((unsigned char *)cpu_addr + (i*size));
0669 break;
0670 }
0671 }
0672 retval = 0;
0673 out:
0674 return retval;
0675 }
0676
0677
0678 static 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)
0679 {
0680 TW_Command *oldcommand;
0681 TW_Command_Apache *newcommand;
0682 TW_SG_Entry_ISO *sgl;
0683 unsigned int pae = 0;
0684
0685 if ((sizeof(long) < 8) && (sizeof(dma_addr_t) > 4))
0686 pae = 1;
0687
0688 if (TW_OP_OUT(full_command_packet->command.newcommand.opcode__reserved) == TW_OP_EXECUTE_SCSI) {
0689 newcommand = &full_command_packet->command.newcommand;
0690 newcommand->request_id__lunl =
0691 cpu_to_le16(TW_REQ_LUN_IN(TW_LUN_OUT(newcommand->request_id__lunl), request_id));
0692 if (length) {
0693 newcommand->sg_list[0].address = TW_CPU_TO_SGL(dma_handle + sizeof(TW_Ioctl_Buf_Apache) - 1);
0694 newcommand->sg_list[0].length = TW_CPU_TO_SGL(length);
0695 }
0696 newcommand->sgl_entries__lunh =
0697 cpu_to_le16(TW_REQ_LUN_IN(TW_LUN_OUT(newcommand->sgl_entries__lunh), length ? 1 : 0));
0698 } else {
0699 oldcommand = &full_command_packet->command.oldcommand;
0700 oldcommand->request_id = request_id;
0701
0702 if (TW_SGL_OUT(oldcommand->opcode__sgloffset)) {
0703
0704 sgl = (TW_SG_Entry_ISO *)((u32 *)oldcommand+oldcommand->size - (sizeof(TW_SG_Entry_ISO)/4) + pae + (sizeof(dma_addr_t) > 4 ? 1 : 0));
0705 sgl->address = TW_CPU_TO_SGL(dma_handle + sizeof(TW_Ioctl_Buf_Apache) - 1);
0706 sgl->length = TW_CPU_TO_SGL(length);
0707 oldcommand->size += pae;
0708 oldcommand->size += sizeof(dma_addr_t) > 4 ? 1 : 0;
0709 }
0710 }
0711 }
0712
0713
0714
0715 static long twl_chrdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
0716 {
0717 long timeout;
0718 unsigned long *cpu_addr, data_buffer_length_adjusted = 0, flags = 0;
0719 dma_addr_t dma_handle;
0720 int request_id = 0;
0721 TW_Ioctl_Driver_Command driver_command;
0722 struct inode *inode = file_inode(file);
0723 TW_Ioctl_Buf_Apache *tw_ioctl;
0724 TW_Command_Full *full_command_packet;
0725 TW_Device_Extension *tw_dev = twl_device_extension_list[iminor(inode)];
0726 int retval = -EFAULT;
0727 void __user *argp = (void __user *)arg;
0728
0729 mutex_lock(&twl_chrdev_mutex);
0730
0731
0732 if (mutex_lock_interruptible(&tw_dev->ioctl_lock)) {
0733 retval = -EINTR;
0734 goto out;
0735 }
0736
0737
0738 if (copy_from_user(&driver_command, argp, sizeof(TW_Ioctl_Driver_Command)))
0739 goto out2;
0740
0741
0742 if (driver_command.buffer_length > TW_MAX_SECTORS * 2048) {
0743 retval = -EINVAL;
0744 goto out2;
0745 }
0746
0747
0748 data_buffer_length_adjusted = (driver_command.buffer_length + 511) & ~511;
0749
0750
0751 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);
0752 if (!cpu_addr) {
0753 retval = -ENOMEM;
0754 goto out2;
0755 }
0756
0757 tw_ioctl = (TW_Ioctl_Buf_Apache *)cpu_addr;
0758
0759
0760 if (copy_from_user(tw_ioctl, argp, driver_command.buffer_length + sizeof(TW_Ioctl_Buf_Apache) - 1))
0761 goto out3;
0762
0763
0764 switch (cmd) {
0765 case TW_IOCTL_FIRMWARE_PASS_THROUGH:
0766 spin_lock_irqsave(tw_dev->host->host_lock, flags);
0767 twl_get_request_id(tw_dev, &request_id);
0768
0769
0770 tw_dev->srb[request_id] = NULL;
0771
0772
0773 tw_dev->chrdev_request_id = request_id;
0774
0775 full_command_packet = (TW_Command_Full *)&tw_ioctl->firmware_command;
0776
0777
0778 twl_load_sgl(tw_dev, full_command_packet, request_id, dma_handle, data_buffer_length_adjusted);
0779
0780 memcpy(tw_dev->command_packet_virt[request_id], &(tw_ioctl->firmware_command), sizeof(TW_Command_Full));
0781
0782
0783 twl_post_command_packet(tw_dev, request_id);
0784 spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
0785
0786 timeout = TW_IOCTL_CHRDEV_TIMEOUT*HZ;
0787
0788
0789 timeout = wait_event_timeout(tw_dev->ioctl_wqueue, tw_dev->chrdev_request_id == TW_IOCTL_CHRDEV_FREE, timeout);
0790
0791
0792 if (tw_dev->chrdev_request_id != TW_IOCTL_CHRDEV_FREE) {
0793
0794 printk(KERN_WARNING "3w-sas: scsi%d: WARNING: (0x%02X:0x%04X): Character ioctl (0x%x) timed out, resetting card.\n",
0795 tw_dev->host->host_no, TW_DRIVER, 0x6,
0796 cmd);
0797 retval = -EIO;
0798 twl_reset_device_extension(tw_dev, 1);
0799 goto out3;
0800 }
0801
0802
0803 memcpy(&(tw_ioctl->firmware_command), tw_dev->command_packet_virt[request_id], sizeof(TW_Command_Full));
0804
0805
0806 spin_lock_irqsave(tw_dev->host->host_lock, flags);
0807 tw_dev->posted_request_count--;
0808 tw_dev->state[request_id] = TW_S_COMPLETED;
0809 twl_free_request_id(tw_dev, request_id);
0810 spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
0811 break;
0812 default:
0813 retval = -ENOTTY;
0814 goto out3;
0815 }
0816
0817
0818 if (copy_to_user(argp, tw_ioctl, sizeof(TW_Ioctl_Buf_Apache) + driver_command.buffer_length - 1) == 0)
0819 retval = 0;
0820 out3:
0821
0822 dma_free_coherent(&tw_dev->tw_pci_dev->dev, data_buffer_length_adjusted+sizeof(TW_Ioctl_Buf_Apache) - 1, cpu_addr, dma_handle);
0823 out2:
0824 mutex_unlock(&tw_dev->ioctl_lock);
0825 out:
0826 mutex_unlock(&twl_chrdev_mutex);
0827 return retval;
0828 }
0829
0830
0831 static int twl_chrdev_open(struct inode *inode, struct file *file)
0832 {
0833 unsigned int minor_number;
0834 int retval = -ENODEV;
0835
0836 if (!capable(CAP_SYS_ADMIN)) {
0837 retval = -EACCES;
0838 goto out;
0839 }
0840
0841 minor_number = iminor(inode);
0842 if (minor_number >= twl_device_extension_count)
0843 goto out;
0844 retval = 0;
0845 out:
0846 return retval;
0847 }
0848
0849
0850 static const struct file_operations twl_fops = {
0851 .owner = THIS_MODULE,
0852 .unlocked_ioctl = twl_chrdev_ioctl,
0853 .open = twl_chrdev_open,
0854 .release = NULL,
0855 .llseek = noop_llseek,
0856 };
0857
0858
0859 static int twl_fill_sense(TW_Device_Extension *tw_dev, int i, int request_id, int copy_sense, int print_host)
0860 {
0861 TW_Command_Apache_Header *header;
0862 TW_Command_Full *full_command_packet;
0863 unsigned short error;
0864 char *error_str;
0865
0866 header = tw_dev->sense_buffer_virt[i];
0867 full_command_packet = tw_dev->command_packet_virt[request_id];
0868
0869
0870 error_str = &(header->err_specific_desc[strlen(header->err_specific_desc) + 1]);
0871
0872
0873 error = le16_to_cpu(header->status_block.error);
0874 if ((error != TW_ERROR_LOGICAL_UNIT_NOT_SUPPORTED) && (error != TW_ERROR_UNIT_OFFLINE) && (error != TW_ERROR_INVALID_FIELD_IN_CDB)) {
0875 if (print_host)
0876 printk(KERN_WARNING "3w-sas: scsi%d: ERROR: (0x%02X:0x%04X): %s:%s.\n",
0877 tw_dev->host->host_no,
0878 TW_MESSAGE_SOURCE_CONTROLLER_ERROR,
0879 header->status_block.error,
0880 error_str,
0881 header->err_specific_desc);
0882 else
0883 printk(KERN_WARNING "3w-sas: ERROR: (0x%02X:0x%04X): %s:%s.\n",
0884 TW_MESSAGE_SOURCE_CONTROLLER_ERROR,
0885 header->status_block.error,
0886 error_str,
0887 header->err_specific_desc);
0888 }
0889
0890 if (copy_sense) {
0891 memcpy(tw_dev->srb[request_id]->sense_buffer, header->sense_data, TW_SENSE_DATA_LENGTH);
0892 tw_dev->srb[request_id]->result = (full_command_packet->command.newcommand.status << 1);
0893 goto out;
0894 }
0895 out:
0896 return 1;
0897 }
0898
0899
0900 static void twl_free_device_extension(TW_Device_Extension *tw_dev)
0901 {
0902 if (tw_dev->command_packet_virt[0])
0903 dma_free_coherent(&tw_dev->tw_pci_dev->dev,
0904 sizeof(TW_Command_Full)*TW_Q_LENGTH,
0905 tw_dev->command_packet_virt[0],
0906 tw_dev->command_packet_phys[0]);
0907
0908 if (tw_dev->generic_buffer_virt[0])
0909 dma_free_coherent(&tw_dev->tw_pci_dev->dev,
0910 TW_SECTOR_SIZE*TW_Q_LENGTH,
0911 tw_dev->generic_buffer_virt[0],
0912 tw_dev->generic_buffer_phys[0]);
0913
0914 if (tw_dev->sense_buffer_virt[0])
0915 dma_free_coherent(&tw_dev->tw_pci_dev->dev,
0916 sizeof(TW_Command_Apache_Header)*
0917 TW_Q_LENGTH,
0918 tw_dev->sense_buffer_virt[0],
0919 tw_dev->sense_buffer_phys[0]);
0920
0921 kfree(tw_dev->event_queue[0]);
0922 }
0923
0924
0925 static void *twl_get_param(TW_Device_Extension *tw_dev, int request_id, int table_id, int parameter_id, int parameter_size_bytes)
0926 {
0927 TW_Command_Full *full_command_packet;
0928 TW_Command *command_packet;
0929 TW_Param_Apache *param;
0930 void *retval = NULL;
0931
0932
0933 full_command_packet = tw_dev->command_packet_virt[request_id];
0934 memset(full_command_packet, 0, sizeof(TW_Command_Full));
0935 command_packet = &full_command_packet->command.oldcommand;
0936
0937 command_packet->opcode__sgloffset = TW_OPSGL_IN(2, TW_OP_GET_PARAM);
0938 command_packet->size = TW_COMMAND_SIZE;
0939 command_packet->request_id = request_id;
0940 command_packet->byte6_offset.block_count = cpu_to_le16(1);
0941
0942
0943 param = (TW_Param_Apache *)tw_dev->generic_buffer_virt[request_id];
0944 memset(param, 0, TW_SECTOR_SIZE);
0945 param->table_id = cpu_to_le16(table_id | 0x8000);
0946 param->parameter_id = cpu_to_le16(parameter_id);
0947 param->parameter_size_bytes = cpu_to_le16(parameter_size_bytes);
0948
0949 command_packet->byte8_offset.param.sgl[0].address = TW_CPU_TO_SGL(tw_dev->generic_buffer_phys[request_id]);
0950 command_packet->byte8_offset.param.sgl[0].length = TW_CPU_TO_SGL(TW_SECTOR_SIZE);
0951
0952
0953 twl_post_command_packet(tw_dev, request_id);
0954
0955
0956 if (twl_poll_response(tw_dev, request_id, 30))
0957 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x7, "No valid response during get param")
0958 else
0959 retval = (void *)&(param->data[0]);
0960
0961 tw_dev->posted_request_count--;
0962 tw_dev->state[request_id] = TW_S_INITIAL;
0963
0964 return retval;
0965 }
0966
0967
0968 static int twl_initconnection(TW_Device_Extension *tw_dev, int message_credits,
0969 u32 set_features, unsigned short current_fw_srl,
0970 unsigned short current_fw_arch_id,
0971 unsigned short current_fw_branch,
0972 unsigned short current_fw_build,
0973 unsigned short *fw_on_ctlr_srl,
0974 unsigned short *fw_on_ctlr_arch_id,
0975 unsigned short *fw_on_ctlr_branch,
0976 unsigned short *fw_on_ctlr_build,
0977 u32 *init_connect_result)
0978 {
0979 TW_Command_Full *full_command_packet;
0980 TW_Initconnect *tw_initconnect;
0981 int request_id = 0, retval = 1;
0982
0983
0984 full_command_packet = tw_dev->command_packet_virt[request_id];
0985 memset(full_command_packet, 0, sizeof(TW_Command_Full));
0986 full_command_packet->header.header_desc.size_header = 128;
0987
0988 tw_initconnect = (TW_Initconnect *)&full_command_packet->command.oldcommand;
0989 tw_initconnect->opcode__reserved = TW_OPRES_IN(0, TW_OP_INIT_CONNECTION);
0990 tw_initconnect->request_id = request_id;
0991 tw_initconnect->message_credits = cpu_to_le16(message_credits);
0992 tw_initconnect->features = set_features;
0993
0994
0995 tw_initconnect->features |= sizeof(dma_addr_t) > 4 ? 1 : 0;
0996
0997 tw_initconnect->features = cpu_to_le32(tw_initconnect->features);
0998
0999 if (set_features & TW_EXTENDED_INIT_CONNECT) {
1000 tw_initconnect->size = TW_INIT_COMMAND_PACKET_SIZE_EXTENDED;
1001 tw_initconnect->fw_srl = cpu_to_le16(current_fw_srl);
1002 tw_initconnect->fw_arch_id = cpu_to_le16(current_fw_arch_id);
1003 tw_initconnect->fw_branch = cpu_to_le16(current_fw_branch);
1004 tw_initconnect->fw_build = cpu_to_le16(current_fw_build);
1005 } else
1006 tw_initconnect->size = TW_INIT_COMMAND_PACKET_SIZE;
1007
1008
1009 twl_post_command_packet(tw_dev, request_id);
1010
1011
1012 if (twl_poll_response(tw_dev, request_id, 30)) {
1013 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x8, "No valid response during init connection");
1014 } else {
1015 if (set_features & TW_EXTENDED_INIT_CONNECT) {
1016 *fw_on_ctlr_srl = le16_to_cpu(tw_initconnect->fw_srl);
1017 *fw_on_ctlr_arch_id = le16_to_cpu(tw_initconnect->fw_arch_id);
1018 *fw_on_ctlr_branch = le16_to_cpu(tw_initconnect->fw_branch);
1019 *fw_on_ctlr_build = le16_to_cpu(tw_initconnect->fw_build);
1020 *init_connect_result = le32_to_cpu(tw_initconnect->result);
1021 }
1022 retval = 0;
1023 }
1024
1025 tw_dev->posted_request_count--;
1026 tw_dev->state[request_id] = TW_S_INITIAL;
1027
1028 return retval;
1029 }
1030
1031
1032 static int twl_initialize_device_extension(TW_Device_Extension *tw_dev)
1033 {
1034 int i, retval = 1;
1035
1036
1037 if (twl_allocate_memory(tw_dev, sizeof(TW_Command_Full), 0)) {
1038 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x9, "Command packet memory allocation failed");
1039 goto out;
1040 }
1041
1042
1043 if (twl_allocate_memory(tw_dev, TW_SECTOR_SIZE, 1)) {
1044 TW_PRINTK(tw_dev->host, TW_DRIVER, 0xa, "Generic memory allocation failed");
1045 goto out;
1046 }
1047
1048
1049 if (twl_allocate_memory(tw_dev, sizeof(TW_Command_Apache_Header), 2)) {
1050 TW_PRINTK(tw_dev->host, TW_DRIVER, 0xb, "Sense buffer allocation failed");
1051 goto out;
1052 }
1053
1054
1055 tw_dev->event_queue[0] = kcalloc(TW_Q_LENGTH, sizeof(TW_Event), GFP_KERNEL);
1056 if (!tw_dev->event_queue[0]) {
1057 TW_PRINTK(tw_dev->host, TW_DRIVER, 0xc, "Event info memory allocation failed");
1058 goto out;
1059 }
1060
1061 for (i = 0; i < TW_Q_LENGTH; i++) {
1062 tw_dev->event_queue[i] = (TW_Event *)((unsigned char *)tw_dev->event_queue[0] + (i * sizeof(TW_Event)));
1063 tw_dev->free_queue[i] = i;
1064 tw_dev->state[i] = TW_S_INITIAL;
1065 }
1066
1067 tw_dev->free_head = TW_Q_START;
1068 tw_dev->free_tail = TW_Q_START;
1069 tw_dev->error_sequence_id = 1;
1070 tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE;
1071
1072 mutex_init(&tw_dev->ioctl_lock);
1073 init_waitqueue_head(&tw_dev->ioctl_wqueue);
1074
1075 retval = 0;
1076 out:
1077 return retval;
1078 }
1079
1080
1081 static int twl_handle_attention_interrupt(TW_Device_Extension *tw_dev)
1082 {
1083 int retval = 1;
1084 u32 request_id, doorbell;
1085
1086
1087 doorbell = readl(TWL_HOBDB_REG_ADDR(tw_dev));
1088
1089
1090 if (doorbell & TWL_DOORBELL_CONTROLLER_ERROR) {
1091 TW_PRINTK(tw_dev->host, TW_DRIVER, 0xd, "Microcontroller Error: clearing");
1092 goto out;
1093 }
1094
1095
1096 if (doorbell & TWL_DOORBELL_ATTENTION_INTERRUPT) {
1097 if (!(test_and_set_bit(TW_IN_ATTENTION_LOOP, &tw_dev->flags))) {
1098 twl_get_request_id(tw_dev, &request_id);
1099 if (twl_aen_read_queue(tw_dev, request_id)) {
1100 tw_dev->state[request_id] = TW_S_COMPLETED;
1101 twl_free_request_id(tw_dev, request_id);
1102 clear_bit(TW_IN_ATTENTION_LOOP, &tw_dev->flags);
1103 }
1104 }
1105 }
1106
1107 retval = 0;
1108 out:
1109
1110 TWL_CLEAR_DB_INTERRUPT(tw_dev);
1111
1112
1113 readl(TWL_HOBDBC_REG_ADDR(tw_dev));
1114
1115 return retval;
1116 }
1117
1118
1119 static irqreturn_t twl_interrupt(int irq, void *dev_instance)
1120 {
1121 TW_Device_Extension *tw_dev = (TW_Device_Extension *)dev_instance;
1122 int i, handled = 0, error = 0;
1123 dma_addr_t mfa = 0;
1124 u32 reg, regl, regh, response, request_id = 0;
1125 struct scsi_cmnd *cmd;
1126 TW_Command_Full *full_command_packet;
1127
1128 spin_lock(tw_dev->host->host_lock);
1129
1130
1131 reg = readl(TWL_HISTAT_REG_ADDR(tw_dev));
1132
1133
1134 if (!(reg & TWL_HISTATUS_VALID_INTERRUPT))
1135 goto twl_interrupt_bail;
1136
1137 handled = 1;
1138
1139
1140 if (test_bit(TW_IN_RESET, &tw_dev->flags))
1141 goto twl_interrupt_bail;
1142
1143
1144 if (reg & TWL_HISTATUS_ATTENTION_INTERRUPT) {
1145 if (twl_handle_attention_interrupt(tw_dev)) {
1146 TWL_MASK_INTERRUPTS(tw_dev);
1147 goto twl_interrupt_bail;
1148 }
1149 }
1150
1151
1152 while (reg & TWL_HISTATUS_RESPONSE_INTERRUPT) {
1153 if (sizeof(dma_addr_t) > 4) {
1154 regh = readl(TWL_HOBQPH_REG_ADDR(tw_dev));
1155 regl = readl(TWL_HOBQPL_REG_ADDR(tw_dev));
1156 mfa = ((u64)regh << 32) | regl;
1157 } else
1158 mfa = readl(TWL_HOBQPL_REG_ADDR(tw_dev));
1159
1160 error = 0;
1161 response = (u32)mfa;
1162
1163
1164 if (!TW_NOTMFA_OUT(response)) {
1165 for (i=0;i<TW_Q_LENGTH;i++) {
1166 if (tw_dev->sense_buffer_phys[i] == mfa) {
1167 request_id = le16_to_cpu(tw_dev->sense_buffer_virt[i]->header_desc.request_id);
1168 if (tw_dev->srb[request_id] != NULL)
1169 error = twl_fill_sense(tw_dev, i, request_id, 1, 1);
1170 else {
1171
1172 if (request_id != tw_dev->chrdev_request_id)
1173 error = twl_fill_sense(tw_dev, i, request_id, 0, 1);
1174 else
1175 memcpy(tw_dev->command_packet_virt[request_id], tw_dev->sense_buffer_virt[i], sizeof(TW_Command_Apache_Header));
1176 }
1177
1178
1179 writel((u32)((u64)tw_dev->sense_buffer_phys[i] >> 32), TWL_HOBQPH_REG_ADDR(tw_dev));
1180 writel((u32)tw_dev->sense_buffer_phys[i], TWL_HOBQPL_REG_ADDR(tw_dev));
1181 break;
1182 }
1183 }
1184 } else
1185 request_id = TW_RESID_OUT(response);
1186
1187 full_command_packet = tw_dev->command_packet_virt[request_id];
1188
1189
1190 if (tw_dev->state[request_id] != TW_S_POSTED) {
1191 if (tw_dev->srb[request_id] != NULL) {
1192 TW_PRINTK(tw_dev->host, TW_DRIVER, 0xe, "Received a request id that wasn't posted");
1193 TWL_MASK_INTERRUPTS(tw_dev);
1194 goto twl_interrupt_bail;
1195 }
1196 }
1197
1198
1199 if (tw_dev->srb[request_id] == NULL) {
1200 if (request_id != tw_dev->chrdev_request_id) {
1201 if (twl_aen_complete(tw_dev, request_id))
1202 TW_PRINTK(tw_dev->host, TW_DRIVER, 0xf, "Error completing AEN during attention interrupt");
1203 } else {
1204 tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE;
1205 wake_up(&tw_dev->ioctl_wqueue);
1206 }
1207 } else {
1208 cmd = tw_dev->srb[request_id];
1209
1210 if (!error)
1211 cmd->result = (DID_OK << 16);
1212
1213
1214 if ((scsi_sg_count(cmd) <= 1) && (full_command_packet->command.newcommand.status == 0)) {
1215 if (full_command_packet->command.newcommand.sg_list[0].length < scsi_bufflen(tw_dev->srb[request_id]))
1216 scsi_set_resid(cmd, scsi_bufflen(cmd) - full_command_packet->command.newcommand.sg_list[0].length);
1217 }
1218
1219
1220 scsi_dma_unmap(cmd);
1221 scsi_done(cmd);
1222 tw_dev->state[request_id] = TW_S_COMPLETED;
1223 twl_free_request_id(tw_dev, request_id);
1224 tw_dev->posted_request_count--;
1225 }
1226
1227
1228 reg = readl(TWL_HISTAT_REG_ADDR(tw_dev));
1229 }
1230
1231 twl_interrupt_bail:
1232 spin_unlock(tw_dev->host->host_lock);
1233 return IRQ_RETVAL(handled);
1234 }
1235
1236
1237 static int twl_poll_register(TW_Device_Extension *tw_dev, void *reg, u32 value, u32 result, int seconds)
1238 {
1239 unsigned long before;
1240 int retval = 1;
1241 u32 reg_value;
1242
1243 reg_value = readl(reg);
1244 before = jiffies;
1245
1246 while ((reg_value & value) != result) {
1247 reg_value = readl(reg);
1248 if (time_after(jiffies, before + HZ * seconds))
1249 goto out;
1250 msleep(50);
1251 }
1252 retval = 0;
1253 out:
1254 return retval;
1255 }
1256
1257
1258 static int twl_reset_sequence(TW_Device_Extension *tw_dev, int soft_reset)
1259 {
1260 int retval = 1;
1261 int i = 0;
1262 u32 status = 0;
1263 unsigned short fw_on_ctlr_srl = 0, fw_on_ctlr_arch_id = 0;
1264 unsigned short fw_on_ctlr_branch = 0, fw_on_ctlr_build = 0;
1265 u32 init_connect_result = 0;
1266 int tries = 0;
1267 int do_soft_reset = soft_reset;
1268
1269 while (tries < TW_MAX_RESET_TRIES) {
1270
1271 if (do_soft_reset) {
1272 TWL_SOFT_RESET(tw_dev);
1273
1274
1275 if (twl_poll_register(tw_dev, TWL_SCRPD3_REG_ADDR(tw_dev), TWL_CONTROLLER_READY, 0x0, 30)) {
1276 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x10, "Controller never went non-ready during reset sequence");
1277 tries++;
1278 continue;
1279 }
1280 if (twl_poll_register(tw_dev, TWL_SCRPD3_REG_ADDR(tw_dev), TWL_CONTROLLER_READY, TWL_CONTROLLER_READY, 60)) {
1281 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x11, "Controller not ready during reset sequence");
1282 tries++;
1283 continue;
1284 }
1285 }
1286
1287
1288 if (twl_initconnection(tw_dev, TW_INIT_MESSAGE_CREDITS,
1289 TW_EXTENDED_INIT_CONNECT, TW_CURRENT_DRIVER_SRL,
1290 TW_9750_ARCH_ID, TW_CURRENT_DRIVER_BRANCH,
1291 TW_CURRENT_DRIVER_BUILD, &fw_on_ctlr_srl,
1292 &fw_on_ctlr_arch_id, &fw_on_ctlr_branch,
1293 &fw_on_ctlr_build, &init_connect_result)) {
1294 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x12, "Initconnection failed while checking SRL");
1295 do_soft_reset = 1;
1296 tries++;
1297 continue;
1298 }
1299
1300
1301 while (i < TW_Q_LENGTH) {
1302 writel((u32)((u64)tw_dev->sense_buffer_phys[i] >> 32), TWL_HOBQPH_REG_ADDR(tw_dev));
1303 writel((u32)tw_dev->sense_buffer_phys[i], TWL_HOBQPL_REG_ADDR(tw_dev));
1304
1305
1306 status = readl(TWL_STATUS_REG_ADDR(tw_dev));
1307 if (!(status & TWL_STATUS_OVERRUN_SUBMIT))
1308 i++;
1309 }
1310
1311
1312 status = readl(TWL_STATUS_REG_ADDR(tw_dev));
1313 if (status) {
1314 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x13, "Bad controller status after loading sense buffers");
1315 do_soft_reset = 1;
1316 tries++;
1317 continue;
1318 }
1319
1320
1321 if (twl_aen_drain_queue(tw_dev, soft_reset)) {
1322 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x14, "AEN drain failed during reset sequence");
1323 do_soft_reset = 1;
1324 tries++;
1325 continue;
1326 }
1327
1328
1329 strncpy(tw_dev->tw_compat_info.driver_version, TW_DRIVER_VERSION, strlen(TW_DRIVER_VERSION));
1330 tw_dev->tw_compat_info.driver_srl_high = TW_CURRENT_DRIVER_SRL;
1331 tw_dev->tw_compat_info.driver_branch_high = TW_CURRENT_DRIVER_BRANCH;
1332 tw_dev->tw_compat_info.driver_build_high = TW_CURRENT_DRIVER_BUILD;
1333 tw_dev->tw_compat_info.driver_srl_low = TW_BASE_FW_SRL;
1334 tw_dev->tw_compat_info.driver_branch_low = TW_BASE_FW_BRANCH;
1335 tw_dev->tw_compat_info.driver_build_low = TW_BASE_FW_BUILD;
1336 tw_dev->tw_compat_info.fw_on_ctlr_srl = fw_on_ctlr_srl;
1337 tw_dev->tw_compat_info.fw_on_ctlr_branch = fw_on_ctlr_branch;
1338 tw_dev->tw_compat_info.fw_on_ctlr_build = fw_on_ctlr_build;
1339
1340
1341 retval = 0;
1342 goto out;
1343 }
1344 out:
1345 return retval;
1346 }
1347
1348
1349 static int twl_reset_device_extension(TW_Device_Extension *tw_dev, int ioctl_reset)
1350 {
1351 int i = 0, retval = 1;
1352 unsigned long flags = 0;
1353
1354
1355 if (ioctl_reset)
1356 scsi_block_requests(tw_dev->host);
1357
1358 set_bit(TW_IN_RESET, &tw_dev->flags);
1359 TWL_MASK_INTERRUPTS(tw_dev);
1360 TWL_CLEAR_DB_INTERRUPT(tw_dev);
1361
1362 spin_lock_irqsave(tw_dev->host->host_lock, flags);
1363
1364
1365 for (i = 0; i < TW_Q_LENGTH; i++) {
1366 if ((tw_dev->state[i] != TW_S_FINISHED) &&
1367 (tw_dev->state[i] != TW_S_INITIAL) &&
1368 (tw_dev->state[i] != TW_S_COMPLETED)) {
1369 struct scsi_cmnd *cmd = tw_dev->srb[i];
1370
1371 if (cmd) {
1372 cmd->result = (DID_RESET << 16);
1373 scsi_dma_unmap(cmd);
1374 scsi_done(cmd);
1375 }
1376 }
1377 }
1378
1379
1380 for (i = 0; i < TW_Q_LENGTH; i++) {
1381 tw_dev->free_queue[i] = i;
1382 tw_dev->state[i] = TW_S_INITIAL;
1383 }
1384 tw_dev->free_head = TW_Q_START;
1385 tw_dev->free_tail = TW_Q_START;
1386 tw_dev->posted_request_count = 0;
1387
1388 spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
1389
1390 if (twl_reset_sequence(tw_dev, 1))
1391 goto out;
1392
1393 TWL_UNMASK_INTERRUPTS(tw_dev);
1394
1395 clear_bit(TW_IN_RESET, &tw_dev->flags);
1396 tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE;
1397
1398 retval = 0;
1399 out:
1400 if (ioctl_reset)
1401 scsi_unblock_requests(tw_dev->host);
1402 return retval;
1403 }
1404
1405
1406 static int twl_scsi_biosparam(struct scsi_device *sdev, struct block_device *bdev, sector_t capacity, int geom[])
1407 {
1408 int heads, sectors;
1409
1410 if (capacity >= 0x200000) {
1411 heads = 255;
1412 sectors = 63;
1413 } else {
1414 heads = 64;
1415 sectors = 32;
1416 }
1417
1418 geom[0] = heads;
1419 geom[1] = sectors;
1420 geom[2] = sector_div(capacity, heads * sectors);
1421
1422 return 0;
1423 }
1424
1425
1426 static int twl_scsi_eh_reset(struct scsi_cmnd *SCpnt)
1427 {
1428 TW_Device_Extension *tw_dev = NULL;
1429 int retval = FAILED;
1430
1431 tw_dev = (TW_Device_Extension *)SCpnt->device->host->hostdata;
1432
1433 tw_dev->num_resets++;
1434
1435 sdev_printk(KERN_WARNING, SCpnt->device,
1436 "WARNING: (0x%02X:0x%04X): Command (0x%x) timed out, resetting card.\n",
1437 TW_DRIVER, 0x2c, SCpnt->cmnd[0]);
1438
1439
1440 mutex_lock(&tw_dev->ioctl_lock);
1441
1442
1443 if (twl_reset_device_extension(tw_dev, 0)) {
1444 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x15, "Controller reset failed during scsi host reset");
1445 goto out;
1446 }
1447
1448 retval = SUCCESS;
1449 out:
1450 mutex_unlock(&tw_dev->ioctl_lock);
1451 return retval;
1452 }
1453
1454
1455 static int twl_scsi_queue_lck(struct scsi_cmnd *SCpnt)
1456 {
1457 void (*done)(struct scsi_cmnd *) = scsi_done;
1458 int request_id, retval;
1459 TW_Device_Extension *tw_dev = (TW_Device_Extension *)SCpnt->device->host->hostdata;
1460
1461
1462 if (test_bit(TW_IN_RESET, &tw_dev->flags)) {
1463 retval = SCSI_MLQUEUE_HOST_BUSY;
1464 goto out;
1465 }
1466
1467
1468 twl_get_request_id(tw_dev, &request_id);
1469
1470
1471 tw_dev->srb[request_id] = SCpnt;
1472
1473 retval = twl_scsiop_execute_scsi(tw_dev, request_id, NULL, 0, NULL);
1474 if (retval) {
1475 tw_dev->state[request_id] = TW_S_COMPLETED;
1476 twl_free_request_id(tw_dev, request_id);
1477 SCpnt->result = (DID_ERROR << 16);
1478 done(SCpnt);
1479 retval = 0;
1480 }
1481 out:
1482 return retval;
1483 }
1484
1485 static DEF_SCSI_QCMD(twl_scsi_queue)
1486
1487
1488 static void __twl_shutdown(TW_Device_Extension *tw_dev)
1489 {
1490
1491 TWL_MASK_INTERRUPTS(tw_dev);
1492
1493
1494 free_irq(tw_dev->tw_pci_dev->irq, tw_dev);
1495
1496 printk(KERN_WARNING "3w-sas: Shutting down host %d.\n", tw_dev->host->host_no);
1497
1498
1499 if (twl_initconnection(tw_dev, 1, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL)) {
1500 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x16, "Connection shutdown failed");
1501 } else {
1502 printk(KERN_WARNING "3w-sas: Shutdown complete.\n");
1503 }
1504
1505
1506 TWL_CLEAR_DB_INTERRUPT(tw_dev);
1507 }
1508
1509
1510 static void twl_shutdown(struct pci_dev *pdev)
1511 {
1512 struct Scsi_Host *host = pci_get_drvdata(pdev);
1513 TW_Device_Extension *tw_dev;
1514
1515 if (!host)
1516 return;
1517
1518 tw_dev = (TW_Device_Extension *)host->hostdata;
1519
1520 if (tw_dev->online)
1521 __twl_shutdown(tw_dev);
1522 }
1523
1524
1525 static int twl_slave_configure(struct scsi_device *sdev)
1526 {
1527
1528 blk_queue_rq_timeout(sdev->request_queue, 60 * HZ);
1529
1530 return 0;
1531 }
1532
1533
1534 static struct scsi_host_template driver_template = {
1535 .module = THIS_MODULE,
1536 .name = "3w-sas",
1537 .queuecommand = twl_scsi_queue,
1538 .eh_host_reset_handler = twl_scsi_eh_reset,
1539 .bios_param = twl_scsi_biosparam,
1540 .change_queue_depth = scsi_change_queue_depth,
1541 .can_queue = TW_Q_LENGTH-2,
1542 .slave_configure = twl_slave_configure,
1543 .this_id = -1,
1544 .sg_tablesize = TW_LIBERATOR_MAX_SGL_LENGTH,
1545 .max_sectors = TW_MAX_SECTORS,
1546 .cmd_per_lun = TW_MAX_CMDS_PER_LUN,
1547 .shost_groups = twl_host_groups,
1548 .emulated = 1,
1549 .no_write_same = 1,
1550 };
1551
1552
1553 static int twl_probe(struct pci_dev *pdev, const struct pci_device_id *dev_id)
1554 {
1555 struct Scsi_Host *host = NULL;
1556 TW_Device_Extension *tw_dev;
1557 int retval = -ENODEV;
1558 int *ptr_phycount, phycount=0;
1559
1560 retval = pci_enable_device(pdev);
1561 if (retval) {
1562 TW_PRINTK(host, TW_DRIVER, 0x17, "Failed to enable pci device");
1563 goto out_disable_device;
1564 }
1565
1566 pci_set_master(pdev);
1567 pci_try_set_mwi(pdev);
1568
1569 retval = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
1570 if (retval) {
1571 TW_PRINTK(host, TW_DRIVER, 0x18, "Failed to set dma mask");
1572 retval = -ENODEV;
1573 goto out_disable_device;
1574 }
1575
1576 host = scsi_host_alloc(&driver_template, sizeof(TW_Device_Extension));
1577 if (!host) {
1578 TW_PRINTK(host, TW_DRIVER, 0x19, "Failed to allocate memory for device extension");
1579 retval = -ENOMEM;
1580 goto out_disable_device;
1581 }
1582 tw_dev = shost_priv(host);
1583
1584
1585 tw_dev->host = host;
1586 tw_dev->tw_pci_dev = pdev;
1587
1588 if (twl_initialize_device_extension(tw_dev)) {
1589 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1a, "Failed to initialize device extension");
1590 retval = -ENOMEM;
1591 goto out_free_device_extension;
1592 }
1593
1594
1595 retval = pci_request_regions(pdev, "3w-sas");
1596 if (retval) {
1597 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1b, "Failed to get mem region");
1598 goto out_free_device_extension;
1599 }
1600
1601
1602 tw_dev->base_addr = pci_iomap(pdev, 1, 0);
1603 if (!tw_dev->base_addr) {
1604 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1c, "Failed to ioremap");
1605 retval = -ENOMEM;
1606 goto out_release_mem_region;
1607 }
1608
1609
1610 TWL_MASK_INTERRUPTS(tw_dev);
1611
1612
1613 if (twl_reset_sequence(tw_dev, 0)) {
1614 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1d, "Controller reset failed during probe");
1615 retval = -ENOMEM;
1616 goto out_iounmap;
1617 }
1618
1619
1620 host->max_id = TW_MAX_UNITS;
1621 host->max_cmd_len = TW_MAX_CDB_LEN;
1622 host->max_lun = TW_MAX_LUNS;
1623 host->max_channel = 0;
1624
1625
1626 retval = scsi_add_host(host, &pdev->dev);
1627 if (retval) {
1628 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1e, "scsi add host failed");
1629 goto out_iounmap;
1630 }
1631
1632 pci_set_drvdata(pdev, host);
1633
1634 printk(KERN_WARNING "3w-sas: scsi%d: Found an LSI 3ware %s Controller at 0x%llx, IRQ: %d.\n",
1635 host->host_no,
1636 (char *)twl_get_param(tw_dev, 1, TW_VERSION_TABLE,
1637 TW_PARAM_MODEL, TW_PARAM_MODEL_LENGTH),
1638 (u64)pci_resource_start(pdev, 1), pdev->irq);
1639
1640 ptr_phycount = twl_get_param(tw_dev, 2, TW_PARAM_PHY_SUMMARY_TABLE,
1641 TW_PARAM_PHYCOUNT, TW_PARAM_PHYCOUNT_LENGTH);
1642 if (ptr_phycount)
1643 phycount = le32_to_cpu(*(int *)ptr_phycount);
1644
1645 printk(KERN_WARNING "3w-sas: scsi%d: Firmware %s, BIOS %s, Phys: %d.\n",
1646 host->host_no,
1647 (char *)twl_get_param(tw_dev, 1, TW_VERSION_TABLE,
1648 TW_PARAM_FWVER, TW_PARAM_FWVER_LENGTH),
1649 (char *)twl_get_param(tw_dev, 2, TW_VERSION_TABLE,
1650 TW_PARAM_BIOSVER, TW_PARAM_BIOSVER_LENGTH),
1651 phycount);
1652
1653
1654 if (use_msi && !pci_enable_msi(pdev))
1655 set_bit(TW_USING_MSI, &tw_dev->flags);
1656
1657
1658 retval = request_irq(pdev->irq, twl_interrupt, IRQF_SHARED, "3w-sas", tw_dev);
1659 if (retval) {
1660 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1f, "Error requesting IRQ");
1661 goto out_remove_host;
1662 }
1663
1664 twl_device_extension_list[twl_device_extension_count] = tw_dev;
1665 twl_device_extension_count++;
1666
1667
1668 TWL_UNMASK_INTERRUPTS(tw_dev);
1669
1670
1671 scsi_scan_host(host);
1672
1673
1674 if (sysfs_create_bin_file(&host->shost_dev.kobj, &twl_sysfs_aen_read_attr))
1675 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x20, "Failed to create sysfs binary file: 3ware_aen_read");
1676 if (sysfs_create_bin_file(&host->shost_dev.kobj, &twl_sysfs_compat_info_attr))
1677 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x21, "Failed to create sysfs binary file: 3ware_compat_info");
1678
1679 if (twl_major == -1) {
1680 if ((twl_major = register_chrdev (0, "twl", &twl_fops)) < 0)
1681 TW_PRINTK(host, TW_DRIVER, 0x22, "Failed to register character device");
1682 }
1683 tw_dev->online = 1;
1684 return 0;
1685
1686 out_remove_host:
1687 if (test_bit(TW_USING_MSI, &tw_dev->flags))
1688 pci_disable_msi(pdev);
1689 scsi_remove_host(host);
1690 out_iounmap:
1691 iounmap(tw_dev->base_addr);
1692 out_release_mem_region:
1693 pci_release_regions(pdev);
1694 out_free_device_extension:
1695 twl_free_device_extension(tw_dev);
1696 scsi_host_put(host);
1697 out_disable_device:
1698 pci_disable_device(pdev);
1699
1700 return retval;
1701 }
1702
1703
1704 static void twl_remove(struct pci_dev *pdev)
1705 {
1706 struct Scsi_Host *host = pci_get_drvdata(pdev);
1707 TW_Device_Extension *tw_dev;
1708
1709 if (!host)
1710 return;
1711
1712 tw_dev = (TW_Device_Extension *)host->hostdata;
1713
1714 if (!tw_dev->online)
1715 return;
1716
1717
1718 sysfs_remove_bin_file(&host->shost_dev.kobj, &twl_sysfs_aen_read_attr);
1719 sysfs_remove_bin_file(&host->shost_dev.kobj, &twl_sysfs_compat_info_attr);
1720
1721 scsi_remove_host(tw_dev->host);
1722
1723
1724 if (twl_major >= 0) {
1725 unregister_chrdev(twl_major, "twl");
1726 twl_major = -1;
1727 }
1728
1729
1730 __twl_shutdown(tw_dev);
1731
1732
1733 if (test_bit(TW_USING_MSI, &tw_dev->flags))
1734 pci_disable_msi(pdev);
1735
1736
1737 iounmap(tw_dev->base_addr);
1738
1739
1740 pci_release_regions(pdev);
1741
1742
1743 twl_free_device_extension(tw_dev);
1744
1745 scsi_host_put(tw_dev->host);
1746 pci_disable_device(pdev);
1747 twl_device_extension_count--;
1748 }
1749
1750
1751 static int __maybe_unused twl_suspend(struct device *dev)
1752 {
1753 struct Scsi_Host *host = dev_get_drvdata(dev);
1754 TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata;
1755
1756 printk(KERN_WARNING "3w-sas: Suspending host %d.\n", tw_dev->host->host_no);
1757
1758 TWL_MASK_INTERRUPTS(tw_dev);
1759
1760 free_irq(tw_dev->tw_pci_dev->irq, tw_dev);
1761
1762
1763 if (twl_initconnection(tw_dev, 1, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL)) {
1764 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x23, "Connection shutdown failed during suspend");
1765 } else {
1766 printk(KERN_WARNING "3w-sas: Suspend complete.\n");
1767 }
1768
1769
1770 TWL_CLEAR_DB_INTERRUPT(tw_dev);
1771
1772 return 0;
1773 }
1774
1775
1776 static int __maybe_unused twl_resume(struct device *dev)
1777 {
1778 int retval = 0;
1779 struct pci_dev *pdev = to_pci_dev(dev);
1780 struct Scsi_Host *host = pci_get_drvdata(pdev);
1781 TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata;
1782
1783 printk(KERN_WARNING "3w-sas: Resuming host %d.\n", tw_dev->host->host_no);
1784 pci_try_set_mwi(pdev);
1785
1786 retval = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
1787 if (retval) {
1788 TW_PRINTK(host, TW_DRIVER, 0x25, "Failed to set dma mask during resume");
1789 retval = -ENODEV;
1790 goto out_disable_device;
1791 }
1792
1793
1794 if (twl_reset_sequence(tw_dev, 0)) {
1795 retval = -ENODEV;
1796 goto out_disable_device;
1797 }
1798
1799
1800 retval = request_irq(pdev->irq, twl_interrupt, IRQF_SHARED, "3w-sas", tw_dev);
1801 if (retval) {
1802 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x26, "Error requesting IRQ during resume");
1803 retval = -ENODEV;
1804 goto out_disable_device;
1805 }
1806
1807
1808 if (test_bit(TW_USING_MSI, &tw_dev->flags))
1809 pci_enable_msi(pdev);
1810
1811
1812 TWL_UNMASK_INTERRUPTS(tw_dev);
1813
1814 printk(KERN_WARNING "3w-sas: Resume complete.\n");
1815 return 0;
1816
1817 out_disable_device:
1818 scsi_remove_host(host);
1819
1820 return retval;
1821 }
1822
1823
1824 static struct pci_device_id twl_pci_tbl[] = {
1825 { PCI_VDEVICE(3WARE, PCI_DEVICE_ID_3WARE_9750) },
1826 { }
1827 };
1828 MODULE_DEVICE_TABLE(pci, twl_pci_tbl);
1829
1830 static SIMPLE_DEV_PM_OPS(twl_pm_ops, twl_suspend, twl_resume);
1831
1832
1833 static struct pci_driver twl_driver = {
1834 .name = "3w-sas",
1835 .id_table = twl_pci_tbl,
1836 .probe = twl_probe,
1837 .remove = twl_remove,
1838 .driver.pm = &twl_pm_ops,
1839 .shutdown = twl_shutdown
1840 };
1841
1842
1843 static int __init twl_init(void)
1844 {
1845 printk(KERN_INFO "LSI 3ware SAS/SATA-RAID Controller device driver for Linux v%s.\n", TW_DRIVER_VERSION);
1846
1847 return pci_register_driver(&twl_driver);
1848 }
1849
1850
1851 static void __exit twl_exit(void)
1852 {
1853 pci_unregister_driver(&twl_driver);
1854 }
1855
1856 module_init(twl_init);
1857 module_exit(twl_exit);
1858