Linux 2.6.34-rc3
[pohmelfs.git] / drivers / scsi / 3w-sas.c
blob4d314d740de443f34e28c100f88932c580f42c24
1 /*
2 3w-sas.c -- LSI 3ware SAS/SATA-RAID Controller device driver for Linux.
4 Written By: Adam Radford <linuxraid@lsi.com>
6 Copyright (C) 2009 LSI Corporation.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; version 2 of the License.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 NO WARRANTY
18 THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
19 CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
20 LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
21 MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
22 solely responsible for determining the appropriateness of using and
23 distributing the Program and assumes all risks associated with its
24 exercise of rights under this Agreement, including but not limited to
25 the risks and costs of program errors, damage to or loss of data,
26 programs or equipment, and unavailability or interruption of operations.
28 DISCLAIMER OF LIABILITY
29 NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
30 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31 DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
32 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
33 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
34 USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
35 HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
37 You should have received a copy of the GNU General Public License
38 along with this program; if not, write to the Free Software
39 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
41 Controllers supported by this driver:
43 LSI 3ware 9750 6Gb/s SAS/SATA-RAID
45 Bugs/Comments/Suggestions should be mailed to:
46 linuxraid@lsi.com
48 For more information, goto:
49 http://www.lsi.com
51 History
52 -------
53 3.26.02.000 - Initial driver release.
56 #include <linux/module.h>
57 #include <linux/reboot.h>
58 #include <linux/spinlock.h>
59 #include <linux/interrupt.h>
60 #include <linux/moduleparam.h>
61 #include <linux/errno.h>
62 #include <linux/types.h>
63 #include <linux/delay.h>
64 #include <linux/pci.h>
65 #include <linux/time.h>
66 #include <linux/mutex.h>
67 #include <linux/smp_lock.h>
68 #include <asm/io.h>
69 #include <asm/irq.h>
70 #include <asm/uaccess.h>
71 #include <scsi/scsi.h>
72 #include <scsi/scsi_host.h>
73 #include <scsi/scsi_tcq.h>
74 #include <scsi/scsi_cmnd.h>
75 #include "3w-sas.h"
77 /* Globals */
78 #define TW_DRIVER_VERSION "3.26.02.000"
79 static TW_Device_Extension *twl_device_extension_list[TW_MAX_SLOT];
80 static unsigned int twl_device_extension_count;
81 static int twl_major = -1;
82 extern struct timezone sys_tz;
84 /* Module parameters */
85 MODULE_AUTHOR ("LSI");
86 MODULE_DESCRIPTION ("LSI 3ware SAS/SATA-RAID Linux Driver");
87 MODULE_LICENSE("GPL");
88 MODULE_VERSION(TW_DRIVER_VERSION);
90 static int use_msi;
91 module_param(use_msi, int, S_IRUGO);
92 MODULE_PARM_DESC(use_msi, "Use Message Signaled Interrupts. Default: 0");
94 /* Function prototypes */
95 static int twl_reset_device_extension(TW_Device_Extension *tw_dev, int ioctl_reset);
97 /* Functions */
99 /* This function returns AENs through sysfs */
100 static ssize_t twl_sysfs_aen_read(struct kobject *kobj,
101 struct bin_attribute *bin_attr,
102 char *outbuf, loff_t offset, size_t count)
104 struct device *dev = container_of(kobj, struct device, kobj);
105 struct Scsi_Host *shost = class_to_shost(dev);
106 TW_Device_Extension *tw_dev = (TW_Device_Extension *)shost->hostdata;
107 unsigned long flags = 0;
108 ssize_t ret;
110 if (!capable(CAP_SYS_ADMIN))
111 return -EACCES;
113 spin_lock_irqsave(tw_dev->host->host_lock, flags);
114 ret = memory_read_from_buffer(outbuf, count, &offset, tw_dev->event_queue[0], sizeof(TW_Event) * TW_Q_LENGTH);
115 spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
117 return ret;
118 } /* End twl_sysfs_aen_read() */
120 /* aen_read sysfs attribute initializer */
121 static struct bin_attribute twl_sysfs_aen_read_attr = {
122 .attr = {
123 .name = "3ware_aen_read",
124 .mode = S_IRUSR,
126 .size = 0,
127 .read = twl_sysfs_aen_read
130 /* This function returns driver compatibility info through sysfs */
131 static ssize_t twl_sysfs_compat_info(struct kobject *kobj,
132 struct bin_attribute *bin_attr,
133 char *outbuf, loff_t offset, size_t count)
135 struct device *dev = container_of(kobj, struct device, kobj);
136 struct Scsi_Host *shost = class_to_shost(dev);
137 TW_Device_Extension *tw_dev = (TW_Device_Extension *)shost->hostdata;
138 unsigned long flags = 0;
139 ssize_t ret;
141 if (!capable(CAP_SYS_ADMIN))
142 return -EACCES;
144 spin_lock_irqsave(tw_dev->host->host_lock, flags);
145 ret = memory_read_from_buffer(outbuf, count, &offset, &tw_dev->tw_compat_info, sizeof(TW_Compatibility_Info));
146 spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
148 return ret;
149 } /* End twl_sysfs_compat_info() */
151 /* compat_info sysfs attribute initializer */
152 static struct bin_attribute twl_sysfs_compat_info_attr = {
153 .attr = {
154 .name = "3ware_compat_info",
155 .mode = S_IRUSR,
157 .size = 0,
158 .read = twl_sysfs_compat_info
161 /* Show some statistics about the card */
162 static ssize_t twl_show_stats(struct device *dev,
163 struct device_attribute *attr, char *buf)
165 struct Scsi_Host *host = class_to_shost(dev);
166 TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata;
167 unsigned long flags = 0;
168 ssize_t len;
170 spin_lock_irqsave(tw_dev->host->host_lock, flags);
171 len = snprintf(buf, PAGE_SIZE, "3w-sas Driver version: %s\n"
172 "Current commands posted: %4d\n"
173 "Max commands posted: %4d\n"
174 "Last sgl length: %4d\n"
175 "Max sgl length: %4d\n"
176 "Last sector count: %4d\n"
177 "Max sector count: %4d\n"
178 "SCSI Host Resets: %4d\n"
179 "AEN's: %4d\n",
180 TW_DRIVER_VERSION,
181 tw_dev->posted_request_count,
182 tw_dev->max_posted_request_count,
183 tw_dev->sgl_entries,
184 tw_dev->max_sgl_entries,
185 tw_dev->sector_count,
186 tw_dev->max_sector_count,
187 tw_dev->num_resets,
188 tw_dev->aen_count);
189 spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
190 return len;
191 } /* End twl_show_stats() */
193 /* This function will set a devices queue depth */
194 static int twl_change_queue_depth(struct scsi_device *sdev, int queue_depth,
195 int reason)
197 if (reason != SCSI_QDEPTH_DEFAULT)
198 return -EOPNOTSUPP;
200 if (queue_depth > TW_Q_LENGTH-2)
201 queue_depth = TW_Q_LENGTH-2;
202 scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG, queue_depth);
203 return queue_depth;
204 } /* End twl_change_queue_depth() */
206 /* stats sysfs attribute initializer */
207 static struct device_attribute twl_host_stats_attr = {
208 .attr = {
209 .name = "3ware_stats",
210 .mode = S_IRUGO,
212 .show = twl_show_stats
215 /* Host attributes initializer */
216 static struct device_attribute *twl_host_attrs[] = {
217 &twl_host_stats_attr,
218 NULL,
221 /* This function will look up an AEN severity string */
222 static char *twl_aen_severity_lookup(unsigned char severity_code)
224 char *retval = NULL;
226 if ((severity_code < (unsigned char) TW_AEN_SEVERITY_ERROR) ||
227 (severity_code > (unsigned char) TW_AEN_SEVERITY_DEBUG))
228 goto out;
230 retval = twl_aen_severity_table[severity_code];
231 out:
232 return retval;
233 } /* End twl_aen_severity_lookup() */
235 /* This function will queue an event */
236 static void twl_aen_queue_event(TW_Device_Extension *tw_dev, TW_Command_Apache_Header *header)
238 u32 local_time;
239 struct timeval time;
240 TW_Event *event;
241 unsigned short aen;
242 char host[16];
243 char *error_str;
245 tw_dev->aen_count++;
247 /* Fill out event info */
248 event = tw_dev->event_queue[tw_dev->error_index];
250 host[0] = '\0';
251 if (tw_dev->host)
252 sprintf(host, " scsi%d:", tw_dev->host->host_no);
254 aen = le16_to_cpu(header->status_block.error);
255 memset(event, 0, sizeof(TW_Event));
257 event->severity = TW_SEV_OUT(header->status_block.severity__reserved);
258 do_gettimeofday(&time);
259 local_time = (u32)(time.tv_sec - (sys_tz.tz_minuteswest * 60));
260 event->time_stamp_sec = local_time;
261 event->aen_code = aen;
262 event->retrieved = TW_AEN_NOT_RETRIEVED;
263 event->sequence_id = tw_dev->error_sequence_id;
264 tw_dev->error_sequence_id++;
266 /* Check for embedded error string */
267 error_str = &(header->err_specific_desc[strlen(header->err_specific_desc)+1]);
269 header->err_specific_desc[sizeof(header->err_specific_desc) - 1] = '\0';
270 event->parameter_len = strlen(header->err_specific_desc);
271 memcpy(event->parameter_data, header->err_specific_desc, event->parameter_len + 1 + strlen(error_str));
272 if (event->severity != TW_AEN_SEVERITY_DEBUG)
273 printk(KERN_WARNING "3w-sas:%s AEN: %s (0x%02X:0x%04X): %s:%s.\n",
274 host,
275 twl_aen_severity_lookup(TW_SEV_OUT(header->status_block.severity__reserved)),
276 TW_MESSAGE_SOURCE_CONTROLLER_EVENT, aen, error_str,
277 header->err_specific_desc);
278 else
279 tw_dev->aen_count--;
281 tw_dev->error_index = (tw_dev->error_index + 1 ) % TW_Q_LENGTH;
282 } /* End twl_aen_queue_event() */
284 /* This function will attempt to post a command packet to the board */
285 static int twl_post_command_packet(TW_Device_Extension *tw_dev, int request_id)
287 dma_addr_t command_que_value;
289 command_que_value = tw_dev->command_packet_phys[request_id];
290 command_que_value += TW_COMMAND_OFFSET;
292 /* First write upper 4 bytes */
293 writel((u32)((u64)command_que_value >> 32), TWL_HIBQPH_REG_ADDR(tw_dev));
294 /* Then the lower 4 bytes */
295 writel((u32)(command_que_value | TWL_PULL_MODE), TWL_HIBQPL_REG_ADDR(tw_dev));
297 tw_dev->state[request_id] = TW_S_POSTED;
298 tw_dev->posted_request_count++;
299 if (tw_dev->posted_request_count > tw_dev->max_posted_request_count)
300 tw_dev->max_posted_request_count = tw_dev->posted_request_count;
302 return 0;
303 } /* End twl_post_command_packet() */
305 /* This function will perform a pci-dma mapping for a scatter gather list */
306 static int twl_map_scsi_sg_data(TW_Device_Extension *tw_dev, int request_id)
308 int use_sg;
309 struct scsi_cmnd *cmd = tw_dev->srb[request_id];
311 use_sg = scsi_dma_map(cmd);
312 if (!use_sg)
313 return 0;
314 else if (use_sg < 0) {
315 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1, "Failed to map scatter gather list");
316 return 0;
319 cmd->SCp.phase = TW_PHASE_SGLIST;
320 cmd->SCp.have_data_in = use_sg;
322 return use_sg;
323 } /* End twl_map_scsi_sg_data() */
325 /* This function hands scsi cdb's to the firmware */
326 static int twl_scsiop_execute_scsi(TW_Device_Extension *tw_dev, int request_id, char *cdb, int use_sg, TW_SG_Entry_ISO *sglistarg)
328 TW_Command_Full *full_command_packet;
329 TW_Command_Apache *command_packet;
330 int i, sg_count;
331 struct scsi_cmnd *srb = NULL;
332 struct scatterlist *sglist = NULL, *sg;
333 int retval = 1;
335 if (tw_dev->srb[request_id]) {
336 srb = tw_dev->srb[request_id];
337 if (scsi_sglist(srb))
338 sglist = scsi_sglist(srb);
341 /* Initialize command packet */
342 full_command_packet = tw_dev->command_packet_virt[request_id];
343 full_command_packet->header.header_desc.size_header = 128;
344 full_command_packet->header.status_block.error = 0;
345 full_command_packet->header.status_block.severity__reserved = 0;
347 command_packet = &full_command_packet->command.newcommand;
348 command_packet->status = 0;
349 command_packet->opcode__reserved = TW_OPRES_IN(0, TW_OP_EXECUTE_SCSI);
351 /* We forced 16 byte cdb use earlier */
352 if (!cdb)
353 memcpy(command_packet->cdb, srb->cmnd, TW_MAX_CDB_LEN);
354 else
355 memcpy(command_packet->cdb, cdb, TW_MAX_CDB_LEN);
357 if (srb) {
358 command_packet->unit = srb->device->id;
359 command_packet->request_id__lunl =
360 cpu_to_le16(TW_REQ_LUN_IN(srb->device->lun, request_id));
361 } else {
362 command_packet->request_id__lunl =
363 cpu_to_le16(TW_REQ_LUN_IN(0, request_id));
364 command_packet->unit = 0;
367 command_packet->sgl_offset = 16;
369 if (!sglistarg) {
370 /* Map sglist from scsi layer to cmd packet */
371 if (scsi_sg_count(srb)) {
372 sg_count = twl_map_scsi_sg_data(tw_dev, request_id);
373 if (sg_count == 0)
374 goto out;
376 scsi_for_each_sg(srb, sg, sg_count, i) {
377 command_packet->sg_list[i].address = TW_CPU_TO_SGL(sg_dma_address(sg));
378 command_packet->sg_list[i].length = TW_CPU_TO_SGL(sg_dma_len(sg));
380 command_packet->sgl_entries__lunh = cpu_to_le16(TW_REQ_LUN_IN((srb->device->lun >> 4), scsi_sg_count(tw_dev->srb[request_id])));
382 } else {
383 /* Internal cdb post */
384 for (i = 0; i < use_sg; i++) {
385 command_packet->sg_list[i].address = TW_CPU_TO_SGL(sglistarg[i].address);
386 command_packet->sg_list[i].length = TW_CPU_TO_SGL(sglistarg[i].length);
388 command_packet->sgl_entries__lunh = cpu_to_le16(TW_REQ_LUN_IN(0, use_sg));
391 /* Update some stats */
392 if (srb) {
393 tw_dev->sector_count = scsi_bufflen(srb) / 512;
394 if (tw_dev->sector_count > tw_dev->max_sector_count)
395 tw_dev->max_sector_count = tw_dev->sector_count;
396 tw_dev->sgl_entries = scsi_sg_count(srb);
397 if (tw_dev->sgl_entries > tw_dev->max_sgl_entries)
398 tw_dev->max_sgl_entries = tw_dev->sgl_entries;
401 /* Now post the command to the board */
402 retval = twl_post_command_packet(tw_dev, request_id);
404 out:
405 return retval;
406 } /* End twl_scsiop_execute_scsi() */
408 /* This function will read the aen queue from the isr */
409 static int twl_aen_read_queue(TW_Device_Extension *tw_dev, int request_id)
411 char cdb[TW_MAX_CDB_LEN];
412 TW_SG_Entry_ISO sglist[1];
413 TW_Command_Full *full_command_packet;
414 int retval = 1;
416 full_command_packet = tw_dev->command_packet_virt[request_id];
417 memset(full_command_packet, 0, sizeof(TW_Command_Full));
419 /* Initialize cdb */
420 memset(&cdb, 0, TW_MAX_CDB_LEN);
421 cdb[0] = REQUEST_SENSE; /* opcode */
422 cdb[4] = TW_ALLOCATION_LENGTH; /* allocation length */
424 /* Initialize sglist */
425 memset(&sglist, 0, sizeof(TW_SG_Entry_ISO));
426 sglist[0].length = TW_SECTOR_SIZE;
427 sglist[0].address = tw_dev->generic_buffer_phys[request_id];
429 /* Mark internal command */
430 tw_dev->srb[request_id] = NULL;
432 /* Now post the command packet */
433 if (twl_scsiop_execute_scsi(tw_dev, request_id, cdb, 1, sglist)) {
434 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x2, "Post failed while reading AEN queue");
435 goto out;
437 retval = 0;
438 out:
439 return retval;
440 } /* End twl_aen_read_queue() */
442 /* This function will sync firmware time with the host time */
443 static void twl_aen_sync_time(TW_Device_Extension *tw_dev, int request_id)
445 u32 schedulertime;
446 struct timeval utc;
447 TW_Command_Full *full_command_packet;
448 TW_Command *command_packet;
449 TW_Param_Apache *param;
450 u32 local_time;
452 /* Fill out the command packet */
453 full_command_packet = tw_dev->command_packet_virt[request_id];
454 memset(full_command_packet, 0, sizeof(TW_Command_Full));
455 command_packet = &full_command_packet->command.oldcommand;
456 command_packet->opcode__sgloffset = TW_OPSGL_IN(2, TW_OP_SET_PARAM);
457 command_packet->request_id = request_id;
458 command_packet->byte8_offset.param.sgl[0].address = TW_CPU_TO_SGL(tw_dev->generic_buffer_phys[request_id]);
459 command_packet->byte8_offset.param.sgl[0].length = TW_CPU_TO_SGL(TW_SECTOR_SIZE);
460 command_packet->size = TW_COMMAND_SIZE;
461 command_packet->byte6_offset.parameter_count = cpu_to_le16(1);
463 /* Setup the param */
464 param = (TW_Param_Apache *)tw_dev->generic_buffer_virt[request_id];
465 memset(param, 0, TW_SECTOR_SIZE);
466 param->table_id = cpu_to_le16(TW_TIMEKEEP_TABLE | 0x8000); /* Controller time keep table */
467 param->parameter_id = cpu_to_le16(0x3); /* SchedulerTime */
468 param->parameter_size_bytes = cpu_to_le16(4);
470 /* Convert system time in UTC to local time seconds since last
471 Sunday 12:00AM */
472 do_gettimeofday(&utc);
473 local_time = (u32)(utc.tv_sec - (sys_tz.tz_minuteswest * 60));
474 schedulertime = local_time - (3 * 86400);
475 schedulertime = cpu_to_le32(schedulertime % 604800);
477 memcpy(param->data, &schedulertime, sizeof(u32));
479 /* Mark internal command */
480 tw_dev->srb[request_id] = NULL;
482 /* Now post the command */
483 twl_post_command_packet(tw_dev, request_id);
484 } /* End twl_aen_sync_time() */
486 /* This function will assign an available request id */
487 static void twl_get_request_id(TW_Device_Extension *tw_dev, int *request_id)
489 *request_id = tw_dev->free_queue[tw_dev->free_head];
490 tw_dev->free_head = (tw_dev->free_head + 1) % TW_Q_LENGTH;
491 tw_dev->state[*request_id] = TW_S_STARTED;
492 } /* End twl_get_request_id() */
494 /* This function will free a request id */
495 static void twl_free_request_id(TW_Device_Extension *tw_dev, int request_id)
497 tw_dev->free_queue[tw_dev->free_tail] = request_id;
498 tw_dev->state[request_id] = TW_S_FINISHED;
499 tw_dev->free_tail = (tw_dev->free_tail + 1) % TW_Q_LENGTH;
500 } /* End twl_free_request_id() */
502 /* This function will complete an aen request from the isr */
503 static int twl_aen_complete(TW_Device_Extension *tw_dev, int request_id)
505 TW_Command_Full *full_command_packet;
506 TW_Command *command_packet;
507 TW_Command_Apache_Header *header;
508 unsigned short aen;
509 int retval = 1;
511 header = (TW_Command_Apache_Header *)tw_dev->generic_buffer_virt[request_id];
512 tw_dev->posted_request_count--;
513 aen = le16_to_cpu(header->status_block.error);
514 full_command_packet = tw_dev->command_packet_virt[request_id];
515 command_packet = &full_command_packet->command.oldcommand;
517 /* First check for internal completion of set param for time sync */
518 if (TW_OP_OUT(command_packet->opcode__sgloffset) == TW_OP_SET_PARAM) {
519 /* Keep reading the queue in case there are more aen's */
520 if (twl_aen_read_queue(tw_dev, request_id))
521 goto out2;
522 else {
523 retval = 0;
524 goto out;
528 switch (aen) {
529 case TW_AEN_QUEUE_EMPTY:
530 /* Quit reading the queue if this is the last one */
531 break;
532 case TW_AEN_SYNC_TIME_WITH_HOST:
533 twl_aen_sync_time(tw_dev, request_id);
534 retval = 0;
535 goto out;
536 default:
537 twl_aen_queue_event(tw_dev, header);
539 /* If there are more aen's, keep reading the queue */
540 if (twl_aen_read_queue(tw_dev, request_id))
541 goto out2;
542 else {
543 retval = 0;
544 goto out;
547 retval = 0;
548 out2:
549 tw_dev->state[request_id] = TW_S_COMPLETED;
550 twl_free_request_id(tw_dev, request_id);
551 clear_bit(TW_IN_ATTENTION_LOOP, &tw_dev->flags);
552 out:
553 return retval;
554 } /* End twl_aen_complete() */
556 /* This function will poll for a response */
557 static int twl_poll_response(TW_Device_Extension *tw_dev, int request_id, int seconds)
559 unsigned long before;
560 dma_addr_t mfa;
561 u32 regh, regl;
562 u32 response;
563 int retval = 1;
564 int found = 0;
566 before = jiffies;
568 while (!found) {
569 if (sizeof(dma_addr_t) > 4) {
570 regh = readl(TWL_HOBQPH_REG_ADDR(tw_dev));
571 regl = readl(TWL_HOBQPL_REG_ADDR(tw_dev));
572 mfa = ((u64)regh << 32) | regl;
573 } else
574 mfa = readl(TWL_HOBQPL_REG_ADDR(tw_dev));
576 response = (u32)mfa;
578 if (TW_RESID_OUT(response) == request_id)
579 found = 1;
581 if (time_after(jiffies, before + HZ * seconds))
582 goto out;
584 msleep(50);
586 retval = 0;
587 out:
588 return retval;
589 } /* End twl_poll_response() */
591 /* This function will drain the aen queue */
592 static int twl_aen_drain_queue(TW_Device_Extension *tw_dev, int no_check_reset)
594 int request_id = 0;
595 char cdb[TW_MAX_CDB_LEN];
596 TW_SG_Entry_ISO sglist[1];
597 int finished = 0, count = 0;
598 TW_Command_Full *full_command_packet;
599 TW_Command_Apache_Header *header;
600 unsigned short aen;
601 int first_reset = 0, queue = 0, retval = 1;
603 if (no_check_reset)
604 first_reset = 0;
605 else
606 first_reset = 1;
608 full_command_packet = tw_dev->command_packet_virt[request_id];
609 memset(full_command_packet, 0, sizeof(TW_Command_Full));
611 /* Initialize cdb */
612 memset(&cdb, 0, TW_MAX_CDB_LEN);
613 cdb[0] = REQUEST_SENSE; /* opcode */
614 cdb[4] = TW_ALLOCATION_LENGTH; /* allocation length */
616 /* Initialize sglist */
617 memset(&sglist, 0, sizeof(TW_SG_Entry_ISO));
618 sglist[0].length = TW_SECTOR_SIZE;
619 sglist[0].address = tw_dev->generic_buffer_phys[request_id];
621 /* Mark internal command */
622 tw_dev->srb[request_id] = NULL;
624 do {
625 /* Send command to the board */
626 if (twl_scsiop_execute_scsi(tw_dev, request_id, cdb, 1, sglist)) {
627 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x3, "Error posting request sense");
628 goto out;
631 /* Now poll for completion */
632 if (twl_poll_response(tw_dev, request_id, 30)) {
633 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x4, "No valid response while draining AEN queue");
634 tw_dev->posted_request_count--;
635 goto out;
638 tw_dev->posted_request_count--;
639 header = (TW_Command_Apache_Header *)tw_dev->generic_buffer_virt[request_id];
640 aen = le16_to_cpu(header->status_block.error);
641 queue = 0;
642 count++;
644 switch (aen) {
645 case TW_AEN_QUEUE_EMPTY:
646 if (first_reset != 1)
647 goto out;
648 else
649 finished = 1;
650 break;
651 case TW_AEN_SOFT_RESET:
652 if (first_reset == 0)
653 first_reset = 1;
654 else
655 queue = 1;
656 break;
657 case TW_AEN_SYNC_TIME_WITH_HOST:
658 break;
659 default:
660 queue = 1;
663 /* Now queue an event info */
664 if (queue)
665 twl_aen_queue_event(tw_dev, header);
666 } while ((finished == 0) && (count < TW_MAX_AEN_DRAIN));
668 if (count == TW_MAX_AEN_DRAIN)
669 goto out;
671 retval = 0;
672 out:
673 tw_dev->state[request_id] = TW_S_INITIAL;
674 return retval;
675 } /* End twl_aen_drain_queue() */
677 /* This function will allocate memory and check if it is correctly aligned */
678 static int twl_allocate_memory(TW_Device_Extension *tw_dev, int size, int which)
680 int i;
681 dma_addr_t dma_handle;
682 unsigned long *cpu_addr;
683 int retval = 1;
685 cpu_addr = pci_alloc_consistent(tw_dev->tw_pci_dev, size*TW_Q_LENGTH, &dma_handle);
686 if (!cpu_addr) {
687 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x5, "Memory allocation failed");
688 goto out;
691 memset(cpu_addr, 0, size*TW_Q_LENGTH);
693 for (i = 0; i < TW_Q_LENGTH; i++) {
694 switch(which) {
695 case 0:
696 tw_dev->command_packet_phys[i] = dma_handle+(i*size);
697 tw_dev->command_packet_virt[i] = (TW_Command_Full *)((unsigned char *)cpu_addr + (i*size));
698 break;
699 case 1:
700 tw_dev->generic_buffer_phys[i] = dma_handle+(i*size);
701 tw_dev->generic_buffer_virt[i] = (unsigned long *)((unsigned char *)cpu_addr + (i*size));
702 break;
703 case 2:
704 tw_dev->sense_buffer_phys[i] = dma_handle+(i*size);
705 tw_dev->sense_buffer_virt[i] = (TW_Command_Apache_Header *)((unsigned char *)cpu_addr + (i*size));
706 break;
709 retval = 0;
710 out:
711 return retval;
712 } /* End twl_allocate_memory() */
714 /* This function will load the request id and various sgls for ioctls */
715 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)
717 TW_Command *oldcommand;
718 TW_Command_Apache *newcommand;
719 TW_SG_Entry_ISO *sgl;
720 unsigned int pae = 0;
722 if ((sizeof(long) < 8) && (sizeof(dma_addr_t) > 4))
723 pae = 1;
725 if (TW_OP_OUT(full_command_packet->command.newcommand.opcode__reserved) == TW_OP_EXECUTE_SCSI) {
726 newcommand = &full_command_packet->command.newcommand;
727 newcommand->request_id__lunl =
728 cpu_to_le16(TW_REQ_LUN_IN(TW_LUN_OUT(newcommand->request_id__lunl), request_id));
729 if (length) {
730 newcommand->sg_list[0].address = TW_CPU_TO_SGL(dma_handle + sizeof(TW_Ioctl_Buf_Apache) - 1);
731 newcommand->sg_list[0].length = TW_CPU_TO_SGL(length);
733 newcommand->sgl_entries__lunh =
734 cpu_to_le16(TW_REQ_LUN_IN(TW_LUN_OUT(newcommand->sgl_entries__lunh), length ? 1 : 0));
735 } else {
736 oldcommand = &full_command_packet->command.oldcommand;
737 oldcommand->request_id = request_id;
739 if (TW_SGL_OUT(oldcommand->opcode__sgloffset)) {
740 /* Load the sg list */
741 sgl = (TW_SG_Entry_ISO *)((u32 *)oldcommand+oldcommand->size - (sizeof(TW_SG_Entry_ISO)/4) + pae + (sizeof(dma_addr_t) > 4 ? 1 : 0));
742 sgl->address = TW_CPU_TO_SGL(dma_handle + sizeof(TW_Ioctl_Buf_Apache) - 1);
743 sgl->length = TW_CPU_TO_SGL(length);
744 oldcommand->size += pae;
745 oldcommand->size += sizeof(dma_addr_t) > 4 ? 1 : 0;
748 } /* End twl_load_sgl() */
750 /* This function handles ioctl for the character device
751 This interface is used by smartmontools open source software */
752 static int twl_chrdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
754 long timeout;
755 unsigned long *cpu_addr, data_buffer_length_adjusted = 0, flags = 0;
756 dma_addr_t dma_handle;
757 int request_id = 0;
758 TW_Ioctl_Driver_Command driver_command;
759 TW_Ioctl_Buf_Apache *tw_ioctl;
760 TW_Command_Full *full_command_packet;
761 TW_Device_Extension *tw_dev = twl_device_extension_list[iminor(inode)];
762 int retval = -EFAULT;
763 void __user *argp = (void __user *)arg;
765 /* Only let one of these through at a time */
766 if (mutex_lock_interruptible(&tw_dev->ioctl_lock)) {
767 retval = -EINTR;
768 goto out;
771 /* First copy down the driver command */
772 if (copy_from_user(&driver_command, argp, sizeof(TW_Ioctl_Driver_Command)))
773 goto out2;
775 /* Check data buffer size */
776 if (driver_command.buffer_length > TW_MAX_SECTORS * 2048) {
777 retval = -EINVAL;
778 goto out2;
781 /* Hardware can only do multiple of 512 byte transfers */
782 data_buffer_length_adjusted = (driver_command.buffer_length + 511) & ~511;
784 /* Now allocate ioctl buf memory */
785 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);
786 if (!cpu_addr) {
787 retval = -ENOMEM;
788 goto out2;
791 tw_ioctl = (TW_Ioctl_Buf_Apache *)cpu_addr;
793 /* Now copy down the entire ioctl */
794 if (copy_from_user(tw_ioctl, argp, driver_command.buffer_length + sizeof(TW_Ioctl_Buf_Apache) - 1))
795 goto out3;
797 /* See which ioctl we are doing */
798 switch (cmd) {
799 case TW_IOCTL_FIRMWARE_PASS_THROUGH:
800 spin_lock_irqsave(tw_dev->host->host_lock, flags);
801 twl_get_request_id(tw_dev, &request_id);
803 /* Flag internal command */
804 tw_dev->srb[request_id] = NULL;
806 /* Flag chrdev ioctl */
807 tw_dev->chrdev_request_id = request_id;
809 full_command_packet = (TW_Command_Full *)&tw_ioctl->firmware_command;
811 /* Load request id and sglist for both command types */
812 twl_load_sgl(tw_dev, full_command_packet, request_id, dma_handle, data_buffer_length_adjusted);
814 memcpy(tw_dev->command_packet_virt[request_id], &(tw_ioctl->firmware_command), sizeof(TW_Command_Full));
816 /* Now post the command packet to the controller */
817 twl_post_command_packet(tw_dev, request_id);
818 spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
820 timeout = TW_IOCTL_CHRDEV_TIMEOUT*HZ;
822 /* Now wait for command to complete */
823 timeout = wait_event_timeout(tw_dev->ioctl_wqueue, tw_dev->chrdev_request_id == TW_IOCTL_CHRDEV_FREE, timeout);
825 /* We timed out, and didn't get an interrupt */
826 if (tw_dev->chrdev_request_id != TW_IOCTL_CHRDEV_FREE) {
827 /* Now we need to reset the board */
828 printk(KERN_WARNING "3w-sas: scsi%d: WARNING: (0x%02X:0x%04X): Character ioctl (0x%x) timed out, resetting card.\n",
829 tw_dev->host->host_no, TW_DRIVER, 0x6,
830 cmd);
831 retval = -EIO;
832 twl_reset_device_extension(tw_dev, 1);
833 goto out3;
836 /* Now copy in the command packet response */
837 memcpy(&(tw_ioctl->firmware_command), tw_dev->command_packet_virt[request_id], sizeof(TW_Command_Full));
839 /* Now complete the io */
840 spin_lock_irqsave(tw_dev->host->host_lock, flags);
841 tw_dev->posted_request_count--;
842 tw_dev->state[request_id] = TW_S_COMPLETED;
843 twl_free_request_id(tw_dev, request_id);
844 spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
845 break;
846 default:
847 retval = -ENOTTY;
848 goto out3;
851 /* Now copy the entire response to userspace */
852 if (copy_to_user(argp, tw_ioctl, sizeof(TW_Ioctl_Buf_Apache) + driver_command.buffer_length - 1) == 0)
853 retval = 0;
854 out3:
855 /* Now free ioctl buf memory */
856 dma_free_coherent(&tw_dev->tw_pci_dev->dev, data_buffer_length_adjusted+sizeof(TW_Ioctl_Buf_Apache) - 1, cpu_addr, dma_handle);
857 out2:
858 mutex_unlock(&tw_dev->ioctl_lock);
859 out:
860 return retval;
861 } /* End twl_chrdev_ioctl() */
863 /* This function handles open for the character device */
864 static int twl_chrdev_open(struct inode *inode, struct file *file)
866 unsigned int minor_number;
867 int retval = -ENODEV;
869 if (!capable(CAP_SYS_ADMIN)) {
870 retval = -EACCES;
871 goto out;
874 cycle_kernel_lock();
875 minor_number = iminor(inode);
876 if (minor_number >= twl_device_extension_count)
877 goto out;
878 retval = 0;
879 out:
880 return retval;
881 } /* End twl_chrdev_open() */
883 /* File operations struct for character device */
884 static const struct file_operations twl_fops = {
885 .owner = THIS_MODULE,
886 .ioctl = twl_chrdev_ioctl,
887 .open = twl_chrdev_open,
888 .release = NULL
891 /* This function passes sense data from firmware to scsi layer */
892 static int twl_fill_sense(TW_Device_Extension *tw_dev, int i, int request_id, int copy_sense, int print_host)
894 TW_Command_Apache_Header *header;
895 TW_Command_Full *full_command_packet;
896 unsigned short error;
897 char *error_str;
898 int retval = 1;
900 header = tw_dev->sense_buffer_virt[i];
901 full_command_packet = tw_dev->command_packet_virt[request_id];
903 /* Get embedded firmware error string */
904 error_str = &(header->err_specific_desc[strlen(header->err_specific_desc) + 1]);
906 /* Don't print error for Logical unit not supported during rollcall */
907 error = le16_to_cpu(header->status_block.error);
908 if ((error != TW_ERROR_LOGICAL_UNIT_NOT_SUPPORTED) && (error != TW_ERROR_UNIT_OFFLINE) && (error != TW_ERROR_INVALID_FIELD_IN_CDB)) {
909 if (print_host)
910 printk(KERN_WARNING "3w-sas: scsi%d: ERROR: (0x%02X:0x%04X): %s:%s.\n",
911 tw_dev->host->host_no,
912 TW_MESSAGE_SOURCE_CONTROLLER_ERROR,
913 header->status_block.error,
914 error_str,
915 header->err_specific_desc);
916 else
917 printk(KERN_WARNING "3w-sas: ERROR: (0x%02X:0x%04X): %s:%s.\n",
918 TW_MESSAGE_SOURCE_CONTROLLER_ERROR,
919 header->status_block.error,
920 error_str,
921 header->err_specific_desc);
924 if (copy_sense) {
925 memcpy(tw_dev->srb[request_id]->sense_buffer, header->sense_data, TW_SENSE_DATA_LENGTH);
926 tw_dev->srb[request_id]->result = (full_command_packet->command.newcommand.status << 1);
927 goto out;
929 out:
930 return retval;
931 } /* End twl_fill_sense() */
933 /* This function will free up device extension resources */
934 static void twl_free_device_extension(TW_Device_Extension *tw_dev)
936 if (tw_dev->command_packet_virt[0])
937 pci_free_consistent(tw_dev->tw_pci_dev,
938 sizeof(TW_Command_Full)*TW_Q_LENGTH,
939 tw_dev->command_packet_virt[0],
940 tw_dev->command_packet_phys[0]);
942 if (tw_dev->generic_buffer_virt[0])
943 pci_free_consistent(tw_dev->tw_pci_dev,
944 TW_SECTOR_SIZE*TW_Q_LENGTH,
945 tw_dev->generic_buffer_virt[0],
946 tw_dev->generic_buffer_phys[0]);
948 if (tw_dev->sense_buffer_virt[0])
949 pci_free_consistent(tw_dev->tw_pci_dev,
950 sizeof(TW_Command_Apache_Header)*
951 TW_Q_LENGTH,
952 tw_dev->sense_buffer_virt[0],
953 tw_dev->sense_buffer_phys[0]);
955 kfree(tw_dev->event_queue[0]);
956 } /* End twl_free_device_extension() */
958 /* This function will get parameter table entries from the firmware */
959 static void *twl_get_param(TW_Device_Extension *tw_dev, int request_id, int table_id, int parameter_id, int parameter_size_bytes)
961 TW_Command_Full *full_command_packet;
962 TW_Command *command_packet;
963 TW_Param_Apache *param;
964 void *retval = NULL;
966 /* Setup the command packet */
967 full_command_packet = tw_dev->command_packet_virt[request_id];
968 memset(full_command_packet, 0, sizeof(TW_Command_Full));
969 command_packet = &full_command_packet->command.oldcommand;
971 command_packet->opcode__sgloffset = TW_OPSGL_IN(2, TW_OP_GET_PARAM);
972 command_packet->size = TW_COMMAND_SIZE;
973 command_packet->request_id = request_id;
974 command_packet->byte6_offset.block_count = cpu_to_le16(1);
976 /* Now setup the param */
977 param = (TW_Param_Apache *)tw_dev->generic_buffer_virt[request_id];
978 memset(param, 0, TW_SECTOR_SIZE);
979 param->table_id = cpu_to_le16(table_id | 0x8000);
980 param->parameter_id = cpu_to_le16(parameter_id);
981 param->parameter_size_bytes = cpu_to_le16(parameter_size_bytes);
983 command_packet->byte8_offset.param.sgl[0].address = TW_CPU_TO_SGL(tw_dev->generic_buffer_phys[request_id]);
984 command_packet->byte8_offset.param.sgl[0].length = TW_CPU_TO_SGL(TW_SECTOR_SIZE);
986 /* Post the command packet to the board */
987 twl_post_command_packet(tw_dev, request_id);
989 /* Poll for completion */
990 if (twl_poll_response(tw_dev, request_id, 30))
991 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x7, "No valid response during get param")
992 else
993 retval = (void *)&(param->data[0]);
995 tw_dev->posted_request_count--;
996 tw_dev->state[request_id] = TW_S_INITIAL;
998 return retval;
999 } /* End twl_get_param() */
1001 /* This function will send an initconnection command to controller */
1002 static int twl_initconnection(TW_Device_Extension *tw_dev, int message_credits,
1003 u32 set_features, unsigned short current_fw_srl,
1004 unsigned short current_fw_arch_id,
1005 unsigned short current_fw_branch,
1006 unsigned short current_fw_build,
1007 unsigned short *fw_on_ctlr_srl,
1008 unsigned short *fw_on_ctlr_arch_id,
1009 unsigned short *fw_on_ctlr_branch,
1010 unsigned short *fw_on_ctlr_build,
1011 u32 *init_connect_result)
1013 TW_Command_Full *full_command_packet;
1014 TW_Initconnect *tw_initconnect;
1015 int request_id = 0, retval = 1;
1017 /* Initialize InitConnection command packet */
1018 full_command_packet = tw_dev->command_packet_virt[request_id];
1019 memset(full_command_packet, 0, sizeof(TW_Command_Full));
1020 full_command_packet->header.header_desc.size_header = 128;
1022 tw_initconnect = (TW_Initconnect *)&full_command_packet->command.oldcommand;
1023 tw_initconnect->opcode__reserved = TW_OPRES_IN(0, TW_OP_INIT_CONNECTION);
1024 tw_initconnect->request_id = request_id;
1025 tw_initconnect->message_credits = cpu_to_le16(message_credits);
1026 tw_initconnect->features = set_features;
1028 /* Turn on 64-bit sgl support if we need to */
1029 tw_initconnect->features |= sizeof(dma_addr_t) > 4 ? 1 : 0;
1031 tw_initconnect->features = cpu_to_le32(tw_initconnect->features);
1033 if (set_features & TW_EXTENDED_INIT_CONNECT) {
1034 tw_initconnect->size = TW_INIT_COMMAND_PACKET_SIZE_EXTENDED;
1035 tw_initconnect->fw_srl = cpu_to_le16(current_fw_srl);
1036 tw_initconnect->fw_arch_id = cpu_to_le16(current_fw_arch_id);
1037 tw_initconnect->fw_branch = cpu_to_le16(current_fw_branch);
1038 tw_initconnect->fw_build = cpu_to_le16(current_fw_build);
1039 } else
1040 tw_initconnect->size = TW_INIT_COMMAND_PACKET_SIZE;
1042 /* Send command packet to the board */
1043 twl_post_command_packet(tw_dev, request_id);
1045 /* Poll for completion */
1046 if (twl_poll_response(tw_dev, request_id, 30)) {
1047 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x8, "No valid response during init connection");
1048 } else {
1049 if (set_features & TW_EXTENDED_INIT_CONNECT) {
1050 *fw_on_ctlr_srl = le16_to_cpu(tw_initconnect->fw_srl);
1051 *fw_on_ctlr_arch_id = le16_to_cpu(tw_initconnect->fw_arch_id);
1052 *fw_on_ctlr_branch = le16_to_cpu(tw_initconnect->fw_branch);
1053 *fw_on_ctlr_build = le16_to_cpu(tw_initconnect->fw_build);
1054 *init_connect_result = le32_to_cpu(tw_initconnect->result);
1056 retval = 0;
1059 tw_dev->posted_request_count--;
1060 tw_dev->state[request_id] = TW_S_INITIAL;
1062 return retval;
1063 } /* End twl_initconnection() */
1065 /* This function will initialize the fields of a device extension */
1066 static int twl_initialize_device_extension(TW_Device_Extension *tw_dev)
1068 int i, retval = 1;
1070 /* Initialize command packet buffers */
1071 if (twl_allocate_memory(tw_dev, sizeof(TW_Command_Full), 0)) {
1072 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x9, "Command packet memory allocation failed");
1073 goto out;
1076 /* Initialize generic buffer */
1077 if (twl_allocate_memory(tw_dev, TW_SECTOR_SIZE, 1)) {
1078 TW_PRINTK(tw_dev->host, TW_DRIVER, 0xa, "Generic memory allocation failed");
1079 goto out;
1082 /* Allocate sense buffers */
1083 if (twl_allocate_memory(tw_dev, sizeof(TW_Command_Apache_Header), 2)) {
1084 TW_PRINTK(tw_dev->host, TW_DRIVER, 0xb, "Sense buffer allocation failed");
1085 goto out;
1088 /* Allocate event info space */
1089 tw_dev->event_queue[0] = kcalloc(TW_Q_LENGTH, sizeof(TW_Event), GFP_KERNEL);
1090 if (!tw_dev->event_queue[0]) {
1091 TW_PRINTK(tw_dev->host, TW_DRIVER, 0xc, "Event info memory allocation failed");
1092 goto out;
1095 for (i = 0; i < TW_Q_LENGTH; i++) {
1096 tw_dev->event_queue[i] = (TW_Event *)((unsigned char *)tw_dev->event_queue[0] + (i * sizeof(TW_Event)));
1097 tw_dev->free_queue[i] = i;
1098 tw_dev->state[i] = TW_S_INITIAL;
1101 tw_dev->free_head = TW_Q_START;
1102 tw_dev->free_tail = TW_Q_START;
1103 tw_dev->error_sequence_id = 1;
1104 tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE;
1106 mutex_init(&tw_dev->ioctl_lock);
1107 init_waitqueue_head(&tw_dev->ioctl_wqueue);
1109 retval = 0;
1110 out:
1111 return retval;
1112 } /* End twl_initialize_device_extension() */
1114 /* This function will perform a pci-dma unmap */
1115 static void twl_unmap_scsi_data(TW_Device_Extension *tw_dev, int request_id)
1117 struct scsi_cmnd *cmd = tw_dev->srb[request_id];
1119 if (cmd->SCp.phase == TW_PHASE_SGLIST)
1120 scsi_dma_unmap(cmd);
1121 } /* End twl_unmap_scsi_data() */
1123 /* This function will handle attention interrupts */
1124 static int twl_handle_attention_interrupt(TW_Device_Extension *tw_dev)
1126 int retval = 1;
1127 u32 request_id, doorbell;
1129 /* Read doorbell status */
1130 doorbell = readl(TWL_HOBDB_REG_ADDR(tw_dev));
1132 /* Check for controller errors */
1133 if (doorbell & TWL_DOORBELL_CONTROLLER_ERROR) {
1134 TW_PRINTK(tw_dev->host, TW_DRIVER, 0xd, "Microcontroller Error: clearing");
1135 goto out;
1138 /* Check if we need to perform an AEN drain */
1139 if (doorbell & TWL_DOORBELL_ATTENTION_INTERRUPT) {
1140 if (!(test_and_set_bit(TW_IN_ATTENTION_LOOP, &tw_dev->flags))) {
1141 twl_get_request_id(tw_dev, &request_id);
1142 if (twl_aen_read_queue(tw_dev, request_id)) {
1143 tw_dev->state[request_id] = TW_S_COMPLETED;
1144 twl_free_request_id(tw_dev, request_id);
1145 clear_bit(TW_IN_ATTENTION_LOOP, &tw_dev->flags);
1150 retval = 0;
1151 out:
1152 /* Clear doorbell interrupt */
1153 TWL_CLEAR_DB_INTERRUPT(tw_dev);
1155 /* Make sure the clear was flushed by reading it back */
1156 readl(TWL_HOBDBC_REG_ADDR(tw_dev));
1158 return retval;
1159 } /* End twl_handle_attention_interrupt() */
1161 /* Interrupt service routine */
1162 static irqreturn_t twl_interrupt(int irq, void *dev_instance)
1164 TW_Device_Extension *tw_dev = (TW_Device_Extension *)dev_instance;
1165 int i, handled = 0, error = 0;
1166 dma_addr_t mfa = 0;
1167 u32 reg, regl, regh, response, request_id = 0;
1168 struct scsi_cmnd *cmd;
1169 TW_Command_Full *full_command_packet;
1171 spin_lock(tw_dev->host->host_lock);
1173 /* Read host interrupt status */
1174 reg = readl(TWL_HISTAT_REG_ADDR(tw_dev));
1176 /* Check if this is our interrupt, otherwise bail */
1177 if (!(reg & TWL_HISTATUS_VALID_INTERRUPT))
1178 goto twl_interrupt_bail;
1180 handled = 1;
1182 /* If we are resetting, bail */
1183 if (test_bit(TW_IN_RESET, &tw_dev->flags))
1184 goto twl_interrupt_bail;
1186 /* Attention interrupt */
1187 if (reg & TWL_HISTATUS_ATTENTION_INTERRUPT) {
1188 if (twl_handle_attention_interrupt(tw_dev)) {
1189 TWL_MASK_INTERRUPTS(tw_dev);
1190 goto twl_interrupt_bail;
1194 /* Response interrupt */
1195 while (reg & TWL_HISTATUS_RESPONSE_INTERRUPT) {
1196 if (sizeof(dma_addr_t) > 4) {
1197 regh = readl(TWL_HOBQPH_REG_ADDR(tw_dev));
1198 regl = readl(TWL_HOBQPL_REG_ADDR(tw_dev));
1199 mfa = ((u64)regh << 32) | regl;
1200 } else
1201 mfa = readl(TWL_HOBQPL_REG_ADDR(tw_dev));
1203 error = 0;
1204 response = (u32)mfa;
1206 /* Check for command packet error */
1207 if (!TW_NOTMFA_OUT(response)) {
1208 for (i=0;i<TW_Q_LENGTH;i++) {
1209 if (tw_dev->sense_buffer_phys[i] == mfa) {
1210 request_id = le16_to_cpu(tw_dev->sense_buffer_virt[i]->header_desc.request_id);
1211 if (tw_dev->srb[request_id] != NULL)
1212 error = twl_fill_sense(tw_dev, i, request_id, 1, 1);
1213 else {
1214 /* Skip ioctl error prints */
1215 if (request_id != tw_dev->chrdev_request_id)
1216 error = twl_fill_sense(tw_dev, i, request_id, 0, 1);
1217 else
1218 memcpy(tw_dev->command_packet_virt[request_id], tw_dev->sense_buffer_virt[i], sizeof(TW_Command_Apache_Header));
1221 /* Now re-post the sense buffer */
1222 writel((u32)((u64)tw_dev->sense_buffer_phys[i] >> 32), TWL_HOBQPH_REG_ADDR(tw_dev));
1223 writel((u32)tw_dev->sense_buffer_phys[i], TWL_HOBQPL_REG_ADDR(tw_dev));
1224 break;
1227 } else
1228 request_id = TW_RESID_OUT(response);
1230 full_command_packet = tw_dev->command_packet_virt[request_id];
1232 /* Check for correct state */
1233 if (tw_dev->state[request_id] != TW_S_POSTED) {
1234 if (tw_dev->srb[request_id] != NULL) {
1235 TW_PRINTK(tw_dev->host, TW_DRIVER, 0xe, "Received a request id that wasn't posted");
1236 TWL_MASK_INTERRUPTS(tw_dev);
1237 goto twl_interrupt_bail;
1241 /* Check for internal command completion */
1242 if (tw_dev->srb[request_id] == NULL) {
1243 if (request_id != tw_dev->chrdev_request_id) {
1244 if (twl_aen_complete(tw_dev, request_id))
1245 TW_PRINTK(tw_dev->host, TW_DRIVER, 0xf, "Error completing AEN during attention interrupt");
1246 } else {
1247 tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE;
1248 wake_up(&tw_dev->ioctl_wqueue);
1250 } else {
1251 cmd = tw_dev->srb[request_id];
1253 if (!error)
1254 cmd->result = (DID_OK << 16);
1256 /* Report residual bytes for single sgl */
1257 if ((scsi_sg_count(cmd) <= 1) && (full_command_packet->command.newcommand.status == 0)) {
1258 if (full_command_packet->command.newcommand.sg_list[0].length < scsi_bufflen(tw_dev->srb[request_id]))
1259 scsi_set_resid(cmd, scsi_bufflen(cmd) - full_command_packet->command.newcommand.sg_list[0].length);
1262 /* Now complete the io */
1263 tw_dev->state[request_id] = TW_S_COMPLETED;
1264 twl_free_request_id(tw_dev, request_id);
1265 tw_dev->posted_request_count--;
1266 tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
1267 twl_unmap_scsi_data(tw_dev, request_id);
1270 /* Check for another response interrupt */
1271 reg = readl(TWL_HISTAT_REG_ADDR(tw_dev));
1274 twl_interrupt_bail:
1275 spin_unlock(tw_dev->host->host_lock);
1276 return IRQ_RETVAL(handled);
1277 } /* End twl_interrupt() */
1279 /* This function will poll for a register change */
1280 static int twl_poll_register(TW_Device_Extension *tw_dev, void *reg, u32 value, u32 result, int seconds)
1282 unsigned long before;
1283 int retval = 1;
1284 u32 reg_value;
1286 reg_value = readl(reg);
1287 before = jiffies;
1289 while ((reg_value & value) != result) {
1290 reg_value = readl(reg);
1291 if (time_after(jiffies, before + HZ * seconds))
1292 goto out;
1293 msleep(50);
1295 retval = 0;
1296 out:
1297 return retval;
1298 } /* End twl_poll_register() */
1300 /* This function will reset a controller */
1301 static int twl_reset_sequence(TW_Device_Extension *tw_dev, int soft_reset)
1303 int retval = 1;
1304 int i = 0;
1305 u32 status = 0;
1306 unsigned short fw_on_ctlr_srl = 0, fw_on_ctlr_arch_id = 0;
1307 unsigned short fw_on_ctlr_branch = 0, fw_on_ctlr_build = 0;
1308 u32 init_connect_result = 0;
1309 int tries = 0;
1310 int do_soft_reset = soft_reset;
1312 while (tries < TW_MAX_RESET_TRIES) {
1313 /* Do a soft reset if one is needed */
1314 if (do_soft_reset) {
1315 TWL_SOFT_RESET(tw_dev);
1317 /* Make sure controller is in a good state */
1318 if (twl_poll_register(tw_dev, TWL_SCRPD3_REG_ADDR(tw_dev), TWL_CONTROLLER_READY, 0x0, 30)) {
1319 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x10, "Controller never went non-ready during reset sequence");
1320 tries++;
1321 continue;
1323 if (twl_poll_register(tw_dev, TWL_SCRPD3_REG_ADDR(tw_dev), TWL_CONTROLLER_READY, TWL_CONTROLLER_READY, 60)) {
1324 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x11, "Controller not ready during reset sequence");
1325 tries++;
1326 continue;
1330 /* Initconnect */
1331 if (twl_initconnection(tw_dev, TW_INIT_MESSAGE_CREDITS,
1332 TW_EXTENDED_INIT_CONNECT, TW_CURRENT_DRIVER_SRL,
1333 TW_9750_ARCH_ID, TW_CURRENT_DRIVER_BRANCH,
1334 TW_CURRENT_DRIVER_BUILD, &fw_on_ctlr_srl,
1335 &fw_on_ctlr_arch_id, &fw_on_ctlr_branch,
1336 &fw_on_ctlr_build, &init_connect_result)) {
1337 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x12, "Initconnection failed while checking SRL");
1338 do_soft_reset = 1;
1339 tries++;
1340 continue;
1343 /* Load sense buffers */
1344 while (i < TW_Q_LENGTH) {
1345 writel((u32)((u64)tw_dev->sense_buffer_phys[i] >> 32), TWL_HOBQPH_REG_ADDR(tw_dev));
1346 writel((u32)tw_dev->sense_buffer_phys[i], TWL_HOBQPL_REG_ADDR(tw_dev));
1348 /* Check status for over-run after each write */
1349 status = readl(TWL_STATUS_REG_ADDR(tw_dev));
1350 if (!(status & TWL_STATUS_OVERRUN_SUBMIT))
1351 i++;
1354 /* Now check status */
1355 status = readl(TWL_STATUS_REG_ADDR(tw_dev));
1356 if (status) {
1357 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x13, "Bad controller status after loading sense buffers");
1358 do_soft_reset = 1;
1359 tries++;
1360 continue;
1363 /* Drain the AEN queue */
1364 if (twl_aen_drain_queue(tw_dev, soft_reset)) {
1365 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x14, "AEN drain failed during reset sequence");
1366 do_soft_reset = 1;
1367 tries++;
1368 continue;
1371 /* Load rest of compatibility struct */
1372 strncpy(tw_dev->tw_compat_info.driver_version, TW_DRIVER_VERSION, strlen(TW_DRIVER_VERSION));
1373 tw_dev->tw_compat_info.driver_srl_high = TW_CURRENT_DRIVER_SRL;
1374 tw_dev->tw_compat_info.driver_branch_high = TW_CURRENT_DRIVER_BRANCH;
1375 tw_dev->tw_compat_info.driver_build_high = TW_CURRENT_DRIVER_BUILD;
1376 tw_dev->tw_compat_info.driver_srl_low = TW_BASE_FW_SRL;
1377 tw_dev->tw_compat_info.driver_branch_low = TW_BASE_FW_BRANCH;
1378 tw_dev->tw_compat_info.driver_build_low = TW_BASE_FW_BUILD;
1379 tw_dev->tw_compat_info.fw_on_ctlr_srl = fw_on_ctlr_srl;
1380 tw_dev->tw_compat_info.fw_on_ctlr_branch = fw_on_ctlr_branch;
1381 tw_dev->tw_compat_info.fw_on_ctlr_build = fw_on_ctlr_build;
1383 /* If we got here, controller is in a good state */
1384 retval = 0;
1385 goto out;
1387 out:
1388 return retval;
1389 } /* End twl_reset_sequence() */
1391 /* This function will reset a device extension */
1392 static int twl_reset_device_extension(TW_Device_Extension *tw_dev, int ioctl_reset)
1394 int i = 0, retval = 1;
1395 unsigned long flags = 0;
1397 /* Block SCSI requests while we are resetting */
1398 if (ioctl_reset)
1399 scsi_block_requests(tw_dev->host);
1401 set_bit(TW_IN_RESET, &tw_dev->flags);
1402 TWL_MASK_INTERRUPTS(tw_dev);
1403 TWL_CLEAR_DB_INTERRUPT(tw_dev);
1405 spin_lock_irqsave(tw_dev->host->host_lock, flags);
1407 /* Abort all requests that are in progress */
1408 for (i = 0; i < TW_Q_LENGTH; i++) {
1409 if ((tw_dev->state[i] != TW_S_FINISHED) &&
1410 (tw_dev->state[i] != TW_S_INITIAL) &&
1411 (tw_dev->state[i] != TW_S_COMPLETED)) {
1412 if (tw_dev->srb[i]) {
1413 tw_dev->srb[i]->result = (DID_RESET << 16);
1414 tw_dev->srb[i]->scsi_done(tw_dev->srb[i]);
1415 twl_unmap_scsi_data(tw_dev, i);
1420 /* Reset queues and counts */
1421 for (i = 0; i < TW_Q_LENGTH; i++) {
1422 tw_dev->free_queue[i] = i;
1423 tw_dev->state[i] = TW_S_INITIAL;
1425 tw_dev->free_head = TW_Q_START;
1426 tw_dev->free_tail = TW_Q_START;
1427 tw_dev->posted_request_count = 0;
1429 spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
1431 if (twl_reset_sequence(tw_dev, 1))
1432 goto out;
1434 TWL_UNMASK_INTERRUPTS(tw_dev);
1436 clear_bit(TW_IN_RESET, &tw_dev->flags);
1437 tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE;
1439 retval = 0;
1440 out:
1441 if (ioctl_reset)
1442 scsi_unblock_requests(tw_dev->host);
1443 return retval;
1444 } /* End twl_reset_device_extension() */
1446 /* This funciton returns unit geometry in cylinders/heads/sectors */
1447 static int twl_scsi_biosparam(struct scsi_device *sdev, struct block_device *bdev, sector_t capacity, int geom[])
1449 int heads, sectors;
1450 TW_Device_Extension *tw_dev;
1452 tw_dev = (TW_Device_Extension *)sdev->host->hostdata;
1454 if (capacity >= 0x200000) {
1455 heads = 255;
1456 sectors = 63;
1457 } else {
1458 heads = 64;
1459 sectors = 32;
1462 geom[0] = heads;
1463 geom[1] = sectors;
1464 geom[2] = sector_div(capacity, heads * sectors); /* cylinders */
1466 return 0;
1467 } /* End twl_scsi_biosparam() */
1469 /* This is the new scsi eh reset function */
1470 static int twl_scsi_eh_reset(struct scsi_cmnd *SCpnt)
1472 TW_Device_Extension *tw_dev = NULL;
1473 int retval = FAILED;
1475 tw_dev = (TW_Device_Extension *)SCpnt->device->host->hostdata;
1477 tw_dev->num_resets++;
1479 sdev_printk(KERN_WARNING, SCpnt->device,
1480 "WARNING: (0x%02X:0x%04X): Command (0x%x) timed out, resetting card.\n",
1481 TW_DRIVER, 0x2c, SCpnt->cmnd[0]);
1483 /* Make sure we are not issuing an ioctl or resetting from ioctl */
1484 mutex_lock(&tw_dev->ioctl_lock);
1486 /* Now reset the card and some of the device extension data */
1487 if (twl_reset_device_extension(tw_dev, 0)) {
1488 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x15, "Controller reset failed during scsi host reset");
1489 goto out;
1492 retval = SUCCESS;
1493 out:
1494 mutex_unlock(&tw_dev->ioctl_lock);
1495 return retval;
1496 } /* End twl_scsi_eh_reset() */
1498 /* This is the main scsi queue function to handle scsi opcodes */
1499 static int twl_scsi_queue(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
1501 int request_id, retval;
1502 TW_Device_Extension *tw_dev = (TW_Device_Extension *)SCpnt->device->host->hostdata;
1504 /* If we are resetting due to timed out ioctl, report as busy */
1505 if (test_bit(TW_IN_RESET, &tw_dev->flags)) {
1506 retval = SCSI_MLQUEUE_HOST_BUSY;
1507 goto out;
1510 /* Save done function into scsi_cmnd struct */
1511 SCpnt->scsi_done = done;
1513 /* Get a free request id */
1514 twl_get_request_id(tw_dev, &request_id);
1516 /* Save the scsi command for use by the ISR */
1517 tw_dev->srb[request_id] = SCpnt;
1519 /* Initialize phase to zero */
1520 SCpnt->SCp.phase = TW_PHASE_INITIAL;
1522 retval = twl_scsiop_execute_scsi(tw_dev, request_id, NULL, 0, NULL);
1523 if (retval) {
1524 tw_dev->state[request_id] = TW_S_COMPLETED;
1525 twl_free_request_id(tw_dev, request_id);
1526 SCpnt->result = (DID_ERROR << 16);
1527 done(SCpnt);
1528 retval = 0;
1530 out:
1531 return retval;
1532 } /* End twl_scsi_queue() */
1534 /* This function tells the controller to shut down */
1535 static void __twl_shutdown(TW_Device_Extension *tw_dev)
1537 /* Disable interrupts */
1538 TWL_MASK_INTERRUPTS(tw_dev);
1540 /* Free up the IRQ */
1541 free_irq(tw_dev->tw_pci_dev->irq, tw_dev);
1543 printk(KERN_WARNING "3w-sas: Shutting down host %d.\n", tw_dev->host->host_no);
1545 /* Tell the card we are shutting down */
1546 if (twl_initconnection(tw_dev, 1, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL)) {
1547 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x16, "Connection shutdown failed");
1548 } else {
1549 printk(KERN_WARNING "3w-sas: Shutdown complete.\n");
1552 /* Clear doorbell interrupt just before exit */
1553 TWL_CLEAR_DB_INTERRUPT(tw_dev);
1554 } /* End __twl_shutdown() */
1556 /* Wrapper for __twl_shutdown */
1557 static void twl_shutdown(struct pci_dev *pdev)
1559 struct Scsi_Host *host = pci_get_drvdata(pdev);
1560 TW_Device_Extension *tw_dev;
1562 if (!host)
1563 return;
1565 tw_dev = (TW_Device_Extension *)host->hostdata;
1567 if (tw_dev->online)
1568 __twl_shutdown(tw_dev);
1569 } /* End twl_shutdown() */
1571 /* This function configures unit settings when a unit is coming on-line */
1572 static int twl_slave_configure(struct scsi_device *sdev)
1574 /* Force 60 second timeout */
1575 blk_queue_rq_timeout(sdev->request_queue, 60 * HZ);
1577 return 0;
1578 } /* End twl_slave_configure() */
1580 /* scsi_host_template initializer */
1581 static struct scsi_host_template driver_template = {
1582 .module = THIS_MODULE,
1583 .name = "3w-sas",
1584 .queuecommand = twl_scsi_queue,
1585 .eh_host_reset_handler = twl_scsi_eh_reset,
1586 .bios_param = twl_scsi_biosparam,
1587 .change_queue_depth = twl_change_queue_depth,
1588 .can_queue = TW_Q_LENGTH-2,
1589 .slave_configure = twl_slave_configure,
1590 .this_id = -1,
1591 .sg_tablesize = TW_LIBERATOR_MAX_SGL_LENGTH,
1592 .max_sectors = TW_MAX_SECTORS,
1593 .cmd_per_lun = TW_MAX_CMDS_PER_LUN,
1594 .use_clustering = ENABLE_CLUSTERING,
1595 .shost_attrs = twl_host_attrs,
1596 .emulated = 1
1599 /* This function will probe and initialize a card */
1600 static int __devinit twl_probe(struct pci_dev *pdev, const struct pci_device_id *dev_id)
1602 struct Scsi_Host *host = NULL;
1603 TW_Device_Extension *tw_dev;
1604 int retval = -ENODEV;
1605 int *ptr_phycount, phycount=0;
1607 retval = pci_enable_device(pdev);
1608 if (retval) {
1609 TW_PRINTK(host, TW_DRIVER, 0x17, "Failed to enable pci device");
1610 goto out_disable_device;
1613 pci_set_master(pdev);
1614 pci_try_set_mwi(pdev);
1616 if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64))
1617 || pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)))
1618 if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32))
1619 || pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) {
1620 TW_PRINTK(host, TW_DRIVER, 0x18, "Failed to set dma mask");
1621 retval = -ENODEV;
1622 goto out_disable_device;
1625 host = scsi_host_alloc(&driver_template, sizeof(TW_Device_Extension));
1626 if (!host) {
1627 TW_PRINTK(host, TW_DRIVER, 0x19, "Failed to allocate memory for device extension");
1628 retval = -ENOMEM;
1629 goto out_disable_device;
1631 tw_dev = shost_priv(host);
1633 /* Save values to device extension */
1634 tw_dev->host = host;
1635 tw_dev->tw_pci_dev = pdev;
1637 if (twl_initialize_device_extension(tw_dev)) {
1638 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1a, "Failed to initialize device extension");
1639 goto out_free_device_extension;
1642 /* Request IO regions */
1643 retval = pci_request_regions(pdev, "3w-sas");
1644 if (retval) {
1645 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1b, "Failed to get mem region");
1646 goto out_free_device_extension;
1649 /* Save base address, use region 1 */
1650 tw_dev->base_addr = pci_iomap(pdev, 1, 0);
1651 if (!tw_dev->base_addr) {
1652 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1c, "Failed to ioremap");
1653 goto out_release_mem_region;
1656 /* Disable interrupts on the card */
1657 TWL_MASK_INTERRUPTS(tw_dev);
1659 /* Initialize the card */
1660 if (twl_reset_sequence(tw_dev, 0)) {
1661 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1d, "Controller reset failed during probe");
1662 goto out_iounmap;
1665 /* Set host specific parameters */
1666 host->max_id = TW_MAX_UNITS;
1667 host->max_cmd_len = TW_MAX_CDB_LEN;
1668 host->max_lun = TW_MAX_LUNS;
1669 host->max_channel = 0;
1671 /* Register the card with the kernel SCSI layer */
1672 retval = scsi_add_host(host, &pdev->dev);
1673 if (retval) {
1674 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1e, "scsi add host failed");
1675 goto out_iounmap;
1678 pci_set_drvdata(pdev, host);
1680 printk(KERN_WARNING "3w-sas: scsi%d: Found an LSI 3ware %s Controller at 0x%llx, IRQ: %d.\n",
1681 host->host_no,
1682 (char *)twl_get_param(tw_dev, 1, TW_VERSION_TABLE,
1683 TW_PARAM_MODEL, TW_PARAM_MODEL_LENGTH),
1684 (u64)pci_resource_start(pdev, 1), pdev->irq);
1686 ptr_phycount = twl_get_param(tw_dev, 2, TW_PARAM_PHY_SUMMARY_TABLE,
1687 TW_PARAM_PHYCOUNT, TW_PARAM_PHYCOUNT_LENGTH);
1688 if (ptr_phycount)
1689 phycount = le32_to_cpu(*(int *)ptr_phycount);
1691 printk(KERN_WARNING "3w-sas: scsi%d: Firmware %s, BIOS %s, Phys: %d.\n",
1692 host->host_no,
1693 (char *)twl_get_param(tw_dev, 1, TW_VERSION_TABLE,
1694 TW_PARAM_FWVER, TW_PARAM_FWVER_LENGTH),
1695 (char *)twl_get_param(tw_dev, 2, TW_VERSION_TABLE,
1696 TW_PARAM_BIOSVER, TW_PARAM_BIOSVER_LENGTH),
1697 phycount);
1699 /* Try to enable MSI */
1700 if (use_msi && !pci_enable_msi(pdev))
1701 set_bit(TW_USING_MSI, &tw_dev->flags);
1703 /* Now setup the interrupt handler */
1704 retval = request_irq(pdev->irq, twl_interrupt, IRQF_SHARED, "3w-sas", tw_dev);
1705 if (retval) {
1706 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1f, "Error requesting IRQ");
1707 goto out_remove_host;
1710 twl_device_extension_list[twl_device_extension_count] = tw_dev;
1711 twl_device_extension_count++;
1713 /* Re-enable interrupts on the card */
1714 TWL_UNMASK_INTERRUPTS(tw_dev);
1716 /* Finally, scan the host */
1717 scsi_scan_host(host);
1719 /* Add sysfs binary files */
1720 if (sysfs_create_bin_file(&host->shost_dev.kobj, &twl_sysfs_aen_read_attr))
1721 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x20, "Failed to create sysfs binary file: 3ware_aen_read");
1722 if (sysfs_create_bin_file(&host->shost_dev.kobj, &twl_sysfs_compat_info_attr))
1723 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x21, "Failed to create sysfs binary file: 3ware_compat_info");
1725 if (twl_major == -1) {
1726 if ((twl_major = register_chrdev (0, "twl", &twl_fops)) < 0)
1727 TW_PRINTK(host, TW_DRIVER, 0x22, "Failed to register character device");
1729 tw_dev->online = 1;
1730 return 0;
1732 out_remove_host:
1733 if (test_bit(TW_USING_MSI, &tw_dev->flags))
1734 pci_disable_msi(pdev);
1735 scsi_remove_host(host);
1736 out_iounmap:
1737 iounmap(tw_dev->base_addr);
1738 out_release_mem_region:
1739 pci_release_regions(pdev);
1740 out_free_device_extension:
1741 twl_free_device_extension(tw_dev);
1742 scsi_host_put(host);
1743 out_disable_device:
1744 pci_disable_device(pdev);
1746 return retval;
1747 } /* End twl_probe() */
1749 /* This function is called to remove a device */
1750 static void twl_remove(struct pci_dev *pdev)
1752 struct Scsi_Host *host = pci_get_drvdata(pdev);
1753 TW_Device_Extension *tw_dev;
1755 if (!host)
1756 return;
1758 tw_dev = (TW_Device_Extension *)host->hostdata;
1760 if (!tw_dev->online)
1761 return;
1763 /* Remove sysfs binary files */
1764 sysfs_remove_bin_file(&host->shost_dev.kobj, &twl_sysfs_aen_read_attr);
1765 sysfs_remove_bin_file(&host->shost_dev.kobj, &twl_sysfs_compat_info_attr);
1767 scsi_remove_host(tw_dev->host);
1769 /* Unregister character device */
1770 if (twl_major >= 0) {
1771 unregister_chrdev(twl_major, "twl");
1772 twl_major = -1;
1775 /* Shutdown the card */
1776 __twl_shutdown(tw_dev);
1778 /* Disable MSI if enabled */
1779 if (test_bit(TW_USING_MSI, &tw_dev->flags))
1780 pci_disable_msi(pdev);
1782 /* Free IO remapping */
1783 iounmap(tw_dev->base_addr);
1785 /* Free up the mem region */
1786 pci_release_regions(pdev);
1788 /* Free up device extension resources */
1789 twl_free_device_extension(tw_dev);
1791 scsi_host_put(tw_dev->host);
1792 pci_disable_device(pdev);
1793 twl_device_extension_count--;
1794 } /* End twl_remove() */
1796 #ifdef CONFIG_PM
1797 /* This function is called on PCI suspend */
1798 static int twl_suspend(struct pci_dev *pdev, pm_message_t state)
1800 struct Scsi_Host *host = pci_get_drvdata(pdev);
1801 TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata;
1803 printk(KERN_WARNING "3w-sas: Suspending host %d.\n", tw_dev->host->host_no);
1804 /* Disable interrupts */
1805 TWL_MASK_INTERRUPTS(tw_dev);
1807 free_irq(tw_dev->tw_pci_dev->irq, tw_dev);
1809 /* Tell the card we are shutting down */
1810 if (twl_initconnection(tw_dev, 1, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL)) {
1811 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x23, "Connection shutdown failed during suspend");
1812 } else {
1813 printk(KERN_WARNING "3w-sas: Suspend complete.\n");
1816 /* Clear doorbell interrupt */
1817 TWL_CLEAR_DB_INTERRUPT(tw_dev);
1819 pci_save_state(pdev);
1820 pci_disable_device(pdev);
1821 pci_set_power_state(pdev, pci_choose_state(pdev, state));
1823 return 0;
1824 } /* End twl_suspend() */
1826 /* This function is called on PCI resume */
1827 static int twl_resume(struct pci_dev *pdev)
1829 int retval = 0;
1830 struct Scsi_Host *host = pci_get_drvdata(pdev);
1831 TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata;
1833 printk(KERN_WARNING "3w-sas: Resuming host %d.\n", tw_dev->host->host_no);
1834 pci_set_power_state(pdev, PCI_D0);
1835 pci_enable_wake(pdev, PCI_D0, 0);
1836 pci_restore_state(pdev);
1838 retval = pci_enable_device(pdev);
1839 if (retval) {
1840 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x24, "Enable device failed during resume");
1841 return retval;
1844 pci_set_master(pdev);
1845 pci_try_set_mwi(pdev);
1847 if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64))
1848 || pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)))
1849 if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32))
1850 || pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) {
1851 TW_PRINTK(host, TW_DRIVER, 0x25, "Failed to set dma mask during resume");
1852 retval = -ENODEV;
1853 goto out_disable_device;
1856 /* Initialize the card */
1857 if (twl_reset_sequence(tw_dev, 0)) {
1858 retval = -ENODEV;
1859 goto out_disable_device;
1862 /* Now setup the interrupt handler */
1863 retval = request_irq(pdev->irq, twl_interrupt, IRQF_SHARED, "3w-sas", tw_dev);
1864 if (retval) {
1865 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x26, "Error requesting IRQ during resume");
1866 retval = -ENODEV;
1867 goto out_disable_device;
1870 /* Now enable MSI if enabled */
1871 if (test_bit(TW_USING_MSI, &tw_dev->flags))
1872 pci_enable_msi(pdev);
1874 /* Re-enable interrupts on the card */
1875 TWL_UNMASK_INTERRUPTS(tw_dev);
1877 printk(KERN_WARNING "3w-sas: Resume complete.\n");
1878 return 0;
1880 out_disable_device:
1881 scsi_remove_host(host);
1882 pci_disable_device(pdev);
1884 return retval;
1885 } /* End twl_resume() */
1886 #endif
1888 /* PCI Devices supported by this driver */
1889 static struct pci_device_id twl_pci_tbl[] __devinitdata = {
1890 { PCI_VDEVICE(3WARE, PCI_DEVICE_ID_3WARE_9750) },
1893 MODULE_DEVICE_TABLE(pci, twl_pci_tbl);
1895 /* pci_driver initializer */
1896 static struct pci_driver twl_driver = {
1897 .name = "3w-sas",
1898 .id_table = twl_pci_tbl,
1899 .probe = twl_probe,
1900 .remove = twl_remove,
1901 #ifdef CONFIG_PM
1902 .suspend = twl_suspend,
1903 .resume = twl_resume,
1904 #endif
1905 .shutdown = twl_shutdown
1908 /* This function is called on driver initialization */
1909 static int __init twl_init(void)
1911 printk(KERN_INFO "LSI 3ware SAS/SATA-RAID Controller device driver for Linux v%s.\n", TW_DRIVER_VERSION);
1913 return pci_register_driver(&twl_driver);
1914 } /* End twl_init() */
1916 /* This function is called on driver exit */
1917 static void __exit twl_exit(void)
1919 pci_unregister_driver(&twl_driver);
1920 } /* End twl_exit() */
1922 module_init(twl_init);
1923 module_exit(twl_exit);