sctp: translate host order to network order when setting a hmacid
[linux/fpc-iii.git] / drivers / scsi / 3w-sas.c
blob61702ac00d42f3632eec2e9a310d03d59667c5e2
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/slab.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 DEFINE_MUTEX(twl_chrdev_mutex);
80 static TW_Device_Extension *twl_device_extension_list[TW_MAX_SLOT];
81 static unsigned int twl_device_extension_count;
82 static int twl_major = -1;
83 extern struct timezone sys_tz;
85 /* Module parameters */
86 MODULE_AUTHOR ("LSI");
87 MODULE_DESCRIPTION ("LSI 3ware SAS/SATA-RAID Linux Driver");
88 MODULE_LICENSE("GPL");
89 MODULE_VERSION(TW_DRIVER_VERSION);
91 static int use_msi;
92 module_param(use_msi, int, S_IRUGO);
93 MODULE_PARM_DESC(use_msi, "Use Message Signaled Interrupts. Default: 0");
95 /* Function prototypes */
96 static int twl_reset_device_extension(TW_Device_Extension *tw_dev, int ioctl_reset);
98 /* Functions */
100 /* This function returns AENs through sysfs */
101 static ssize_t twl_sysfs_aen_read(struct file *filp, struct kobject *kobj,
102 struct bin_attribute *bin_attr,
103 char *outbuf, loff_t offset, size_t count)
105 struct device *dev = container_of(kobj, struct device, kobj);
106 struct Scsi_Host *shost = class_to_shost(dev);
107 TW_Device_Extension *tw_dev = (TW_Device_Extension *)shost->hostdata;
108 unsigned long flags = 0;
109 ssize_t ret;
111 if (!capable(CAP_SYS_ADMIN))
112 return -EACCES;
114 spin_lock_irqsave(tw_dev->host->host_lock, flags);
115 ret = memory_read_from_buffer(outbuf, count, &offset, tw_dev->event_queue[0], sizeof(TW_Event) * TW_Q_LENGTH);
116 spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
118 return ret;
119 } /* End twl_sysfs_aen_read() */
121 /* aen_read sysfs attribute initializer */
122 static struct bin_attribute twl_sysfs_aen_read_attr = {
123 .attr = {
124 .name = "3ware_aen_read",
125 .mode = S_IRUSR,
127 .size = 0,
128 .read = twl_sysfs_aen_read
131 /* This function returns driver compatibility info through sysfs */
132 static ssize_t twl_sysfs_compat_info(struct file *filp, struct kobject *kobj,
133 struct bin_attribute *bin_attr,
134 char *outbuf, loff_t offset, size_t count)
136 struct device *dev = container_of(kobj, struct device, kobj);
137 struct Scsi_Host *shost = class_to_shost(dev);
138 TW_Device_Extension *tw_dev = (TW_Device_Extension *)shost->hostdata;
139 unsigned long flags = 0;
140 ssize_t ret;
142 if (!capable(CAP_SYS_ADMIN))
143 return -EACCES;
145 spin_lock_irqsave(tw_dev->host->host_lock, flags);
146 ret = memory_read_from_buffer(outbuf, count, &offset, &tw_dev->tw_compat_info, sizeof(TW_Compatibility_Info));
147 spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
149 return ret;
150 } /* End twl_sysfs_compat_info() */
152 /* compat_info sysfs attribute initializer */
153 static struct bin_attribute twl_sysfs_compat_info_attr = {
154 .attr = {
155 .name = "3ware_compat_info",
156 .mode = S_IRUSR,
158 .size = 0,
159 .read = twl_sysfs_compat_info
162 /* Show some statistics about the card */
163 static ssize_t twl_show_stats(struct device *dev,
164 struct device_attribute *attr, char *buf)
166 struct Scsi_Host *host = class_to_shost(dev);
167 TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata;
168 unsigned long flags = 0;
169 ssize_t len;
171 spin_lock_irqsave(tw_dev->host->host_lock, flags);
172 len = snprintf(buf, PAGE_SIZE, "3w-sas Driver version: %s\n"
173 "Current commands posted: %4d\n"
174 "Max commands posted: %4d\n"
175 "Last sgl length: %4d\n"
176 "Max sgl length: %4d\n"
177 "Last sector count: %4d\n"
178 "Max sector count: %4d\n"
179 "SCSI Host Resets: %4d\n"
180 "AEN's: %4d\n",
181 TW_DRIVER_VERSION,
182 tw_dev->posted_request_count,
183 tw_dev->max_posted_request_count,
184 tw_dev->sgl_entries,
185 tw_dev->max_sgl_entries,
186 tw_dev->sector_count,
187 tw_dev->max_sector_count,
188 tw_dev->num_resets,
189 tw_dev->aen_count);
190 spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
191 return len;
192 } /* End twl_show_stats() */
194 /* This function will set a devices queue depth */
195 static int twl_change_queue_depth(struct scsi_device *sdev, int queue_depth,
196 int reason)
198 if (reason != SCSI_QDEPTH_DEFAULT)
199 return -EOPNOTSUPP;
201 if (queue_depth > TW_Q_LENGTH-2)
202 queue_depth = TW_Q_LENGTH-2;
203 scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG, queue_depth);
204 return queue_depth;
205 } /* End twl_change_queue_depth() */
207 /* stats sysfs attribute initializer */
208 static struct device_attribute twl_host_stats_attr = {
209 .attr = {
210 .name = "3ware_stats",
211 .mode = S_IRUGO,
213 .show = twl_show_stats
216 /* Host attributes initializer */
217 static struct device_attribute *twl_host_attrs[] = {
218 &twl_host_stats_attr,
219 NULL,
222 /* This function will look up an AEN severity string */
223 static char *twl_aen_severity_lookup(unsigned char severity_code)
225 char *retval = NULL;
227 if ((severity_code < (unsigned char) TW_AEN_SEVERITY_ERROR) ||
228 (severity_code > (unsigned char) TW_AEN_SEVERITY_DEBUG))
229 goto out;
231 retval = twl_aen_severity_table[severity_code];
232 out:
233 return retval;
234 } /* End twl_aen_severity_lookup() */
236 /* This function will queue an event */
237 static void twl_aen_queue_event(TW_Device_Extension *tw_dev, TW_Command_Apache_Header *header)
239 u32 local_time;
240 struct timeval time;
241 TW_Event *event;
242 unsigned short aen;
243 char host[16];
244 char *error_str;
246 tw_dev->aen_count++;
248 /* Fill out event info */
249 event = tw_dev->event_queue[tw_dev->error_index];
251 host[0] = '\0';
252 if (tw_dev->host)
253 sprintf(host, " scsi%d:", tw_dev->host->host_no);
255 aen = le16_to_cpu(header->status_block.error);
256 memset(event, 0, sizeof(TW_Event));
258 event->severity = TW_SEV_OUT(header->status_block.severity__reserved);
259 do_gettimeofday(&time);
260 local_time = (u32)(time.tv_sec - (sys_tz.tz_minuteswest * 60));
261 event->time_stamp_sec = local_time;
262 event->aen_code = aen;
263 event->retrieved = TW_AEN_NOT_RETRIEVED;
264 event->sequence_id = tw_dev->error_sequence_id;
265 tw_dev->error_sequence_id++;
267 /* Check for embedded error string */
268 error_str = &(header->err_specific_desc[strlen(header->err_specific_desc)+1]);
270 header->err_specific_desc[sizeof(header->err_specific_desc) - 1] = '\0';
271 event->parameter_len = strlen(header->err_specific_desc);
272 memcpy(event->parameter_data, header->err_specific_desc, event->parameter_len + 1 + strlen(error_str));
273 if (event->severity != TW_AEN_SEVERITY_DEBUG)
274 printk(KERN_WARNING "3w-sas:%s AEN: %s (0x%02X:0x%04X): %s:%s.\n",
275 host,
276 twl_aen_severity_lookup(TW_SEV_OUT(header->status_block.severity__reserved)),
277 TW_MESSAGE_SOURCE_CONTROLLER_EVENT, aen, error_str,
278 header->err_specific_desc);
279 else
280 tw_dev->aen_count--;
282 tw_dev->error_index = (tw_dev->error_index + 1 ) % TW_Q_LENGTH;
283 } /* End twl_aen_queue_event() */
285 /* This function will attempt to post a command packet to the board */
286 static int twl_post_command_packet(TW_Device_Extension *tw_dev, int request_id)
288 dma_addr_t command_que_value;
290 command_que_value = tw_dev->command_packet_phys[request_id];
291 command_que_value += TW_COMMAND_OFFSET;
293 /* First write upper 4 bytes */
294 writel((u32)((u64)command_que_value >> 32), TWL_HIBQPH_REG_ADDR(tw_dev));
295 /* Then the lower 4 bytes */
296 writel((u32)(command_que_value | TWL_PULL_MODE), TWL_HIBQPL_REG_ADDR(tw_dev));
298 tw_dev->state[request_id] = TW_S_POSTED;
299 tw_dev->posted_request_count++;
300 if (tw_dev->posted_request_count > tw_dev->max_posted_request_count)
301 tw_dev->max_posted_request_count = tw_dev->posted_request_count;
303 return 0;
304 } /* End twl_post_command_packet() */
306 /* This function hands scsi cdb's to the firmware */
307 static int twl_scsiop_execute_scsi(TW_Device_Extension *tw_dev, int request_id, char *cdb, int use_sg, TW_SG_Entry_ISO *sglistarg)
309 TW_Command_Full *full_command_packet;
310 TW_Command_Apache *command_packet;
311 int i, sg_count;
312 struct scsi_cmnd *srb = NULL;
313 struct scatterlist *sglist = NULL, *sg;
314 int retval = 1;
316 if (tw_dev->srb[request_id]) {
317 srb = tw_dev->srb[request_id];
318 if (scsi_sglist(srb))
319 sglist = scsi_sglist(srb);
322 /* Initialize command packet */
323 full_command_packet = tw_dev->command_packet_virt[request_id];
324 full_command_packet->header.header_desc.size_header = 128;
325 full_command_packet->header.status_block.error = 0;
326 full_command_packet->header.status_block.severity__reserved = 0;
328 command_packet = &full_command_packet->command.newcommand;
329 command_packet->status = 0;
330 command_packet->opcode__reserved = TW_OPRES_IN(0, TW_OP_EXECUTE_SCSI);
332 /* We forced 16 byte cdb use earlier */
333 if (!cdb)
334 memcpy(command_packet->cdb, srb->cmnd, TW_MAX_CDB_LEN);
335 else
336 memcpy(command_packet->cdb, cdb, TW_MAX_CDB_LEN);
338 if (srb) {
339 command_packet->unit = srb->device->id;
340 command_packet->request_id__lunl =
341 cpu_to_le16(TW_REQ_LUN_IN(srb->device->lun, request_id));
342 } else {
343 command_packet->request_id__lunl =
344 cpu_to_le16(TW_REQ_LUN_IN(0, request_id));
345 command_packet->unit = 0;
348 command_packet->sgl_offset = 16;
350 if (!sglistarg) {
351 /* Map sglist from scsi layer to cmd packet */
352 if (scsi_sg_count(srb)) {
353 sg_count = scsi_dma_map(srb);
354 if (sg_count <= 0)
355 goto out;
357 scsi_for_each_sg(srb, sg, sg_count, i) {
358 command_packet->sg_list[i].address = TW_CPU_TO_SGL(sg_dma_address(sg));
359 command_packet->sg_list[i].length = TW_CPU_TO_SGL(sg_dma_len(sg));
361 command_packet->sgl_entries__lunh = cpu_to_le16(TW_REQ_LUN_IN((srb->device->lun >> 4), scsi_sg_count(tw_dev->srb[request_id])));
363 } else {
364 /* Internal cdb post */
365 for (i = 0; i < use_sg; i++) {
366 command_packet->sg_list[i].address = TW_CPU_TO_SGL(sglistarg[i].address);
367 command_packet->sg_list[i].length = TW_CPU_TO_SGL(sglistarg[i].length);
369 command_packet->sgl_entries__lunh = cpu_to_le16(TW_REQ_LUN_IN(0, use_sg));
372 /* Update some stats */
373 if (srb) {
374 tw_dev->sector_count = scsi_bufflen(srb) / 512;
375 if (tw_dev->sector_count > tw_dev->max_sector_count)
376 tw_dev->max_sector_count = tw_dev->sector_count;
377 tw_dev->sgl_entries = scsi_sg_count(srb);
378 if (tw_dev->sgl_entries > tw_dev->max_sgl_entries)
379 tw_dev->max_sgl_entries = tw_dev->sgl_entries;
382 /* Now post the command to the board */
383 retval = twl_post_command_packet(tw_dev, request_id);
385 out:
386 return retval;
387 } /* End twl_scsiop_execute_scsi() */
389 /* This function will read the aen queue from the isr */
390 static int twl_aen_read_queue(TW_Device_Extension *tw_dev, int request_id)
392 char cdb[TW_MAX_CDB_LEN];
393 TW_SG_Entry_ISO sglist[1];
394 TW_Command_Full *full_command_packet;
395 int retval = 1;
397 full_command_packet = tw_dev->command_packet_virt[request_id];
398 memset(full_command_packet, 0, sizeof(TW_Command_Full));
400 /* Initialize cdb */
401 memset(&cdb, 0, TW_MAX_CDB_LEN);
402 cdb[0] = REQUEST_SENSE; /* opcode */
403 cdb[4] = TW_ALLOCATION_LENGTH; /* allocation length */
405 /* Initialize sglist */
406 memset(&sglist, 0, sizeof(TW_SG_Entry_ISO));
407 sglist[0].length = TW_SECTOR_SIZE;
408 sglist[0].address = tw_dev->generic_buffer_phys[request_id];
410 /* Mark internal command */
411 tw_dev->srb[request_id] = NULL;
413 /* Now post the command packet */
414 if (twl_scsiop_execute_scsi(tw_dev, request_id, cdb, 1, sglist)) {
415 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x2, "Post failed while reading AEN queue");
416 goto out;
418 retval = 0;
419 out:
420 return retval;
421 } /* End twl_aen_read_queue() */
423 /* This function will sync firmware time with the host time */
424 static void twl_aen_sync_time(TW_Device_Extension *tw_dev, int request_id)
426 u32 schedulertime;
427 struct timeval utc;
428 TW_Command_Full *full_command_packet;
429 TW_Command *command_packet;
430 TW_Param_Apache *param;
431 u32 local_time;
433 /* Fill out the command packet */
434 full_command_packet = tw_dev->command_packet_virt[request_id];
435 memset(full_command_packet, 0, sizeof(TW_Command_Full));
436 command_packet = &full_command_packet->command.oldcommand;
437 command_packet->opcode__sgloffset = TW_OPSGL_IN(2, TW_OP_SET_PARAM);
438 command_packet->request_id = request_id;
439 command_packet->byte8_offset.param.sgl[0].address = TW_CPU_TO_SGL(tw_dev->generic_buffer_phys[request_id]);
440 command_packet->byte8_offset.param.sgl[0].length = TW_CPU_TO_SGL(TW_SECTOR_SIZE);
441 command_packet->size = TW_COMMAND_SIZE;
442 command_packet->byte6_offset.parameter_count = cpu_to_le16(1);
444 /* Setup the param */
445 param = (TW_Param_Apache *)tw_dev->generic_buffer_virt[request_id];
446 memset(param, 0, TW_SECTOR_SIZE);
447 param->table_id = cpu_to_le16(TW_TIMEKEEP_TABLE | 0x8000); /* Controller time keep table */
448 param->parameter_id = cpu_to_le16(0x3); /* SchedulerTime */
449 param->parameter_size_bytes = cpu_to_le16(4);
451 /* Convert system time in UTC to local time seconds since last
452 Sunday 12:00AM */
453 do_gettimeofday(&utc);
454 local_time = (u32)(utc.tv_sec - (sys_tz.tz_minuteswest * 60));
455 schedulertime = local_time - (3 * 86400);
456 schedulertime = cpu_to_le32(schedulertime % 604800);
458 memcpy(param->data, &schedulertime, sizeof(u32));
460 /* Mark internal command */
461 tw_dev->srb[request_id] = NULL;
463 /* Now post the command */
464 twl_post_command_packet(tw_dev, request_id);
465 } /* End twl_aen_sync_time() */
467 /* This function will assign an available request id */
468 static void twl_get_request_id(TW_Device_Extension *tw_dev, int *request_id)
470 *request_id = tw_dev->free_queue[tw_dev->free_head];
471 tw_dev->free_head = (tw_dev->free_head + 1) % TW_Q_LENGTH;
472 tw_dev->state[*request_id] = TW_S_STARTED;
473 } /* End twl_get_request_id() */
475 /* This function will free a request id */
476 static void twl_free_request_id(TW_Device_Extension *tw_dev, int request_id)
478 tw_dev->free_queue[tw_dev->free_tail] = request_id;
479 tw_dev->state[request_id] = TW_S_FINISHED;
480 tw_dev->free_tail = (tw_dev->free_tail + 1) % TW_Q_LENGTH;
481 } /* End twl_free_request_id() */
483 /* This function will complete an aen request from the isr */
484 static int twl_aen_complete(TW_Device_Extension *tw_dev, int request_id)
486 TW_Command_Full *full_command_packet;
487 TW_Command *command_packet;
488 TW_Command_Apache_Header *header;
489 unsigned short aen;
490 int retval = 1;
492 header = (TW_Command_Apache_Header *)tw_dev->generic_buffer_virt[request_id];
493 tw_dev->posted_request_count--;
494 aen = le16_to_cpu(header->status_block.error);
495 full_command_packet = tw_dev->command_packet_virt[request_id];
496 command_packet = &full_command_packet->command.oldcommand;
498 /* First check for internal completion of set param for time sync */
499 if (TW_OP_OUT(command_packet->opcode__sgloffset) == TW_OP_SET_PARAM) {
500 /* Keep reading the queue in case there are more aen's */
501 if (twl_aen_read_queue(tw_dev, request_id))
502 goto out2;
503 else {
504 retval = 0;
505 goto out;
509 switch (aen) {
510 case TW_AEN_QUEUE_EMPTY:
511 /* Quit reading the queue if this is the last one */
512 break;
513 case TW_AEN_SYNC_TIME_WITH_HOST:
514 twl_aen_sync_time(tw_dev, request_id);
515 retval = 0;
516 goto out;
517 default:
518 twl_aen_queue_event(tw_dev, header);
520 /* If there are more aen's, keep reading the queue */
521 if (twl_aen_read_queue(tw_dev, request_id))
522 goto out2;
523 else {
524 retval = 0;
525 goto out;
528 retval = 0;
529 out2:
530 tw_dev->state[request_id] = TW_S_COMPLETED;
531 twl_free_request_id(tw_dev, request_id);
532 clear_bit(TW_IN_ATTENTION_LOOP, &tw_dev->flags);
533 out:
534 return retval;
535 } /* End twl_aen_complete() */
537 /* This function will poll for a response */
538 static int twl_poll_response(TW_Device_Extension *tw_dev, int request_id, int seconds)
540 unsigned long before;
541 dma_addr_t mfa;
542 u32 regh, regl;
543 u32 response;
544 int retval = 1;
545 int found = 0;
547 before = jiffies;
549 while (!found) {
550 if (sizeof(dma_addr_t) > 4) {
551 regh = readl(TWL_HOBQPH_REG_ADDR(tw_dev));
552 regl = readl(TWL_HOBQPL_REG_ADDR(tw_dev));
553 mfa = ((u64)regh << 32) | regl;
554 } else
555 mfa = readl(TWL_HOBQPL_REG_ADDR(tw_dev));
557 response = (u32)mfa;
559 if (TW_RESID_OUT(response) == request_id)
560 found = 1;
562 if (time_after(jiffies, before + HZ * seconds))
563 goto out;
565 msleep(50);
567 retval = 0;
568 out:
569 return retval;
570 } /* End twl_poll_response() */
572 /* This function will drain the aen queue */
573 static int twl_aen_drain_queue(TW_Device_Extension *tw_dev, int no_check_reset)
575 int request_id = 0;
576 char cdb[TW_MAX_CDB_LEN];
577 TW_SG_Entry_ISO sglist[1];
578 int finished = 0, count = 0;
579 TW_Command_Full *full_command_packet;
580 TW_Command_Apache_Header *header;
581 unsigned short aen;
582 int first_reset = 0, queue = 0, retval = 1;
584 if (no_check_reset)
585 first_reset = 0;
586 else
587 first_reset = 1;
589 full_command_packet = tw_dev->command_packet_virt[request_id];
590 memset(full_command_packet, 0, sizeof(TW_Command_Full));
592 /* Initialize cdb */
593 memset(&cdb, 0, TW_MAX_CDB_LEN);
594 cdb[0] = REQUEST_SENSE; /* opcode */
595 cdb[4] = TW_ALLOCATION_LENGTH; /* allocation length */
597 /* Initialize sglist */
598 memset(&sglist, 0, sizeof(TW_SG_Entry_ISO));
599 sglist[0].length = TW_SECTOR_SIZE;
600 sglist[0].address = tw_dev->generic_buffer_phys[request_id];
602 /* Mark internal command */
603 tw_dev->srb[request_id] = NULL;
605 do {
606 /* Send command to the board */
607 if (twl_scsiop_execute_scsi(tw_dev, request_id, cdb, 1, sglist)) {
608 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x3, "Error posting request sense");
609 goto out;
612 /* Now poll for completion */
613 if (twl_poll_response(tw_dev, request_id, 30)) {
614 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x4, "No valid response while draining AEN queue");
615 tw_dev->posted_request_count--;
616 goto out;
619 tw_dev->posted_request_count--;
620 header = (TW_Command_Apache_Header *)tw_dev->generic_buffer_virt[request_id];
621 aen = le16_to_cpu(header->status_block.error);
622 queue = 0;
623 count++;
625 switch (aen) {
626 case TW_AEN_QUEUE_EMPTY:
627 if (first_reset != 1)
628 goto out;
629 else
630 finished = 1;
631 break;
632 case TW_AEN_SOFT_RESET:
633 if (first_reset == 0)
634 first_reset = 1;
635 else
636 queue = 1;
637 break;
638 case TW_AEN_SYNC_TIME_WITH_HOST:
639 break;
640 default:
641 queue = 1;
644 /* Now queue an event info */
645 if (queue)
646 twl_aen_queue_event(tw_dev, header);
647 } while ((finished == 0) && (count < TW_MAX_AEN_DRAIN));
649 if (count == TW_MAX_AEN_DRAIN)
650 goto out;
652 retval = 0;
653 out:
654 tw_dev->state[request_id] = TW_S_INITIAL;
655 return retval;
656 } /* End twl_aen_drain_queue() */
658 /* This function will allocate memory and check if it is correctly aligned */
659 static int twl_allocate_memory(TW_Device_Extension *tw_dev, int size, int which)
661 int i;
662 dma_addr_t dma_handle;
663 unsigned long *cpu_addr;
664 int retval = 1;
666 cpu_addr = pci_alloc_consistent(tw_dev->tw_pci_dev, size*TW_Q_LENGTH, &dma_handle);
667 if (!cpu_addr) {
668 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x5, "Memory allocation failed");
669 goto out;
672 memset(cpu_addr, 0, size*TW_Q_LENGTH);
674 for (i = 0; i < TW_Q_LENGTH; i++) {
675 switch(which) {
676 case 0:
677 tw_dev->command_packet_phys[i] = dma_handle+(i*size);
678 tw_dev->command_packet_virt[i] = (TW_Command_Full *)((unsigned char *)cpu_addr + (i*size));
679 break;
680 case 1:
681 tw_dev->generic_buffer_phys[i] = dma_handle+(i*size);
682 tw_dev->generic_buffer_virt[i] = (unsigned long *)((unsigned char *)cpu_addr + (i*size));
683 break;
684 case 2:
685 tw_dev->sense_buffer_phys[i] = dma_handle+(i*size);
686 tw_dev->sense_buffer_virt[i] = (TW_Command_Apache_Header *)((unsigned char *)cpu_addr + (i*size));
687 break;
690 retval = 0;
691 out:
692 return retval;
693 } /* End twl_allocate_memory() */
695 /* This function will load the request id and various sgls for ioctls */
696 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)
698 TW_Command *oldcommand;
699 TW_Command_Apache *newcommand;
700 TW_SG_Entry_ISO *sgl;
701 unsigned int pae = 0;
703 if ((sizeof(long) < 8) && (sizeof(dma_addr_t) > 4))
704 pae = 1;
706 if (TW_OP_OUT(full_command_packet->command.newcommand.opcode__reserved) == TW_OP_EXECUTE_SCSI) {
707 newcommand = &full_command_packet->command.newcommand;
708 newcommand->request_id__lunl =
709 cpu_to_le16(TW_REQ_LUN_IN(TW_LUN_OUT(newcommand->request_id__lunl), request_id));
710 if (length) {
711 newcommand->sg_list[0].address = TW_CPU_TO_SGL(dma_handle + sizeof(TW_Ioctl_Buf_Apache) - 1);
712 newcommand->sg_list[0].length = TW_CPU_TO_SGL(length);
714 newcommand->sgl_entries__lunh =
715 cpu_to_le16(TW_REQ_LUN_IN(TW_LUN_OUT(newcommand->sgl_entries__lunh), length ? 1 : 0));
716 } else {
717 oldcommand = &full_command_packet->command.oldcommand;
718 oldcommand->request_id = request_id;
720 if (TW_SGL_OUT(oldcommand->opcode__sgloffset)) {
721 /* Load the sg list */
722 sgl = (TW_SG_Entry_ISO *)((u32 *)oldcommand+oldcommand->size - (sizeof(TW_SG_Entry_ISO)/4) + pae + (sizeof(dma_addr_t) > 4 ? 1 : 0));
723 sgl->address = TW_CPU_TO_SGL(dma_handle + sizeof(TW_Ioctl_Buf_Apache) - 1);
724 sgl->length = TW_CPU_TO_SGL(length);
725 oldcommand->size += pae;
726 oldcommand->size += sizeof(dma_addr_t) > 4 ? 1 : 0;
729 } /* End twl_load_sgl() */
731 /* This function handles ioctl for the character device
732 This interface is used by smartmontools open source software */
733 static long twl_chrdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
735 long timeout;
736 unsigned long *cpu_addr, data_buffer_length_adjusted = 0, flags = 0;
737 dma_addr_t dma_handle;
738 int request_id = 0;
739 TW_Ioctl_Driver_Command driver_command;
740 struct inode *inode = file_inode(file);
741 TW_Ioctl_Buf_Apache *tw_ioctl;
742 TW_Command_Full *full_command_packet;
743 TW_Device_Extension *tw_dev = twl_device_extension_list[iminor(inode)];
744 int retval = -EFAULT;
745 void __user *argp = (void __user *)arg;
747 mutex_lock(&twl_chrdev_mutex);
749 /* Only let one of these through at a time */
750 if (mutex_lock_interruptible(&tw_dev->ioctl_lock)) {
751 retval = -EINTR;
752 goto out;
755 /* First copy down the driver command */
756 if (copy_from_user(&driver_command, argp, sizeof(TW_Ioctl_Driver_Command)))
757 goto out2;
759 /* Check data buffer size */
760 if (driver_command.buffer_length > TW_MAX_SECTORS * 2048) {
761 retval = -EINVAL;
762 goto out2;
765 /* Hardware can only do multiple of 512 byte transfers */
766 data_buffer_length_adjusted = (driver_command.buffer_length + 511) & ~511;
768 /* Now allocate ioctl buf memory */
769 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);
770 if (!cpu_addr) {
771 retval = -ENOMEM;
772 goto out2;
775 tw_ioctl = (TW_Ioctl_Buf_Apache *)cpu_addr;
777 /* Now copy down the entire ioctl */
778 if (copy_from_user(tw_ioctl, argp, driver_command.buffer_length + sizeof(TW_Ioctl_Buf_Apache) - 1))
779 goto out3;
781 /* See which ioctl we are doing */
782 switch (cmd) {
783 case TW_IOCTL_FIRMWARE_PASS_THROUGH:
784 spin_lock_irqsave(tw_dev->host->host_lock, flags);
785 twl_get_request_id(tw_dev, &request_id);
787 /* Flag internal command */
788 tw_dev->srb[request_id] = NULL;
790 /* Flag chrdev ioctl */
791 tw_dev->chrdev_request_id = request_id;
793 full_command_packet = (TW_Command_Full *)&tw_ioctl->firmware_command;
795 /* Load request id and sglist for both command types */
796 twl_load_sgl(tw_dev, full_command_packet, request_id, dma_handle, data_buffer_length_adjusted);
798 memcpy(tw_dev->command_packet_virt[request_id], &(tw_ioctl->firmware_command), sizeof(TW_Command_Full));
800 /* Now post the command packet to the controller */
801 twl_post_command_packet(tw_dev, request_id);
802 spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
804 timeout = TW_IOCTL_CHRDEV_TIMEOUT*HZ;
806 /* Now wait for command to complete */
807 timeout = wait_event_timeout(tw_dev->ioctl_wqueue, tw_dev->chrdev_request_id == TW_IOCTL_CHRDEV_FREE, timeout);
809 /* We timed out, and didn't get an interrupt */
810 if (tw_dev->chrdev_request_id != TW_IOCTL_CHRDEV_FREE) {
811 /* Now we need to reset the board */
812 printk(KERN_WARNING "3w-sas: scsi%d: WARNING: (0x%02X:0x%04X): Character ioctl (0x%x) timed out, resetting card.\n",
813 tw_dev->host->host_no, TW_DRIVER, 0x6,
814 cmd);
815 retval = -EIO;
816 twl_reset_device_extension(tw_dev, 1);
817 goto out3;
820 /* Now copy in the command packet response */
821 memcpy(&(tw_ioctl->firmware_command), tw_dev->command_packet_virt[request_id], sizeof(TW_Command_Full));
823 /* Now complete the io */
824 spin_lock_irqsave(tw_dev->host->host_lock, flags);
825 tw_dev->posted_request_count--;
826 tw_dev->state[request_id] = TW_S_COMPLETED;
827 twl_free_request_id(tw_dev, request_id);
828 spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
829 break;
830 default:
831 retval = -ENOTTY;
832 goto out3;
835 /* Now copy the entire response to userspace */
836 if (copy_to_user(argp, tw_ioctl, sizeof(TW_Ioctl_Buf_Apache) + driver_command.buffer_length - 1) == 0)
837 retval = 0;
838 out3:
839 /* Now free ioctl buf memory */
840 dma_free_coherent(&tw_dev->tw_pci_dev->dev, data_buffer_length_adjusted+sizeof(TW_Ioctl_Buf_Apache) - 1, cpu_addr, dma_handle);
841 out2:
842 mutex_unlock(&tw_dev->ioctl_lock);
843 out:
844 mutex_unlock(&twl_chrdev_mutex);
845 return retval;
846 } /* End twl_chrdev_ioctl() */
848 /* This function handles open for the character device */
849 static int twl_chrdev_open(struct inode *inode, struct file *file)
851 unsigned int minor_number;
852 int retval = -ENODEV;
854 if (!capable(CAP_SYS_ADMIN)) {
855 retval = -EACCES;
856 goto out;
859 minor_number = iminor(inode);
860 if (minor_number >= twl_device_extension_count)
861 goto out;
862 retval = 0;
863 out:
864 return retval;
865 } /* End twl_chrdev_open() */
867 /* File operations struct for character device */
868 static const struct file_operations twl_fops = {
869 .owner = THIS_MODULE,
870 .unlocked_ioctl = twl_chrdev_ioctl,
871 .open = twl_chrdev_open,
872 .release = NULL,
873 .llseek = noop_llseek,
876 /* This function passes sense data from firmware to scsi layer */
877 static int twl_fill_sense(TW_Device_Extension *tw_dev, int i, int request_id, int copy_sense, int print_host)
879 TW_Command_Apache_Header *header;
880 TW_Command_Full *full_command_packet;
881 unsigned short error;
882 char *error_str;
883 int retval = 1;
885 header = tw_dev->sense_buffer_virt[i];
886 full_command_packet = tw_dev->command_packet_virt[request_id];
888 /* Get embedded firmware error string */
889 error_str = &(header->err_specific_desc[strlen(header->err_specific_desc) + 1]);
891 /* Don't print error for Logical unit not supported during rollcall */
892 error = le16_to_cpu(header->status_block.error);
893 if ((error != TW_ERROR_LOGICAL_UNIT_NOT_SUPPORTED) && (error != TW_ERROR_UNIT_OFFLINE) && (error != TW_ERROR_INVALID_FIELD_IN_CDB)) {
894 if (print_host)
895 printk(KERN_WARNING "3w-sas: scsi%d: ERROR: (0x%02X:0x%04X): %s:%s.\n",
896 tw_dev->host->host_no,
897 TW_MESSAGE_SOURCE_CONTROLLER_ERROR,
898 header->status_block.error,
899 error_str,
900 header->err_specific_desc);
901 else
902 printk(KERN_WARNING "3w-sas: ERROR: (0x%02X:0x%04X): %s:%s.\n",
903 TW_MESSAGE_SOURCE_CONTROLLER_ERROR,
904 header->status_block.error,
905 error_str,
906 header->err_specific_desc);
909 if (copy_sense) {
910 memcpy(tw_dev->srb[request_id]->sense_buffer, header->sense_data, TW_SENSE_DATA_LENGTH);
911 tw_dev->srb[request_id]->result = (full_command_packet->command.newcommand.status << 1);
912 goto out;
914 out:
915 return retval;
916 } /* End twl_fill_sense() */
918 /* This function will free up device extension resources */
919 static void twl_free_device_extension(TW_Device_Extension *tw_dev)
921 if (tw_dev->command_packet_virt[0])
922 pci_free_consistent(tw_dev->tw_pci_dev,
923 sizeof(TW_Command_Full)*TW_Q_LENGTH,
924 tw_dev->command_packet_virt[0],
925 tw_dev->command_packet_phys[0]);
927 if (tw_dev->generic_buffer_virt[0])
928 pci_free_consistent(tw_dev->tw_pci_dev,
929 TW_SECTOR_SIZE*TW_Q_LENGTH,
930 tw_dev->generic_buffer_virt[0],
931 tw_dev->generic_buffer_phys[0]);
933 if (tw_dev->sense_buffer_virt[0])
934 pci_free_consistent(tw_dev->tw_pci_dev,
935 sizeof(TW_Command_Apache_Header)*
936 TW_Q_LENGTH,
937 tw_dev->sense_buffer_virt[0],
938 tw_dev->sense_buffer_phys[0]);
940 kfree(tw_dev->event_queue[0]);
941 } /* End twl_free_device_extension() */
943 /* This function will get parameter table entries from the firmware */
944 static void *twl_get_param(TW_Device_Extension *tw_dev, int request_id, int table_id, int parameter_id, int parameter_size_bytes)
946 TW_Command_Full *full_command_packet;
947 TW_Command *command_packet;
948 TW_Param_Apache *param;
949 void *retval = NULL;
951 /* Setup the command packet */
952 full_command_packet = tw_dev->command_packet_virt[request_id];
953 memset(full_command_packet, 0, sizeof(TW_Command_Full));
954 command_packet = &full_command_packet->command.oldcommand;
956 command_packet->opcode__sgloffset = TW_OPSGL_IN(2, TW_OP_GET_PARAM);
957 command_packet->size = TW_COMMAND_SIZE;
958 command_packet->request_id = request_id;
959 command_packet->byte6_offset.block_count = cpu_to_le16(1);
961 /* Now setup the param */
962 param = (TW_Param_Apache *)tw_dev->generic_buffer_virt[request_id];
963 memset(param, 0, TW_SECTOR_SIZE);
964 param->table_id = cpu_to_le16(table_id | 0x8000);
965 param->parameter_id = cpu_to_le16(parameter_id);
966 param->parameter_size_bytes = cpu_to_le16(parameter_size_bytes);
968 command_packet->byte8_offset.param.sgl[0].address = TW_CPU_TO_SGL(tw_dev->generic_buffer_phys[request_id]);
969 command_packet->byte8_offset.param.sgl[0].length = TW_CPU_TO_SGL(TW_SECTOR_SIZE);
971 /* Post the command packet to the board */
972 twl_post_command_packet(tw_dev, request_id);
974 /* Poll for completion */
975 if (twl_poll_response(tw_dev, request_id, 30))
976 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x7, "No valid response during get param")
977 else
978 retval = (void *)&(param->data[0]);
980 tw_dev->posted_request_count--;
981 tw_dev->state[request_id] = TW_S_INITIAL;
983 return retval;
984 } /* End twl_get_param() */
986 /* This function will send an initconnection command to controller */
987 static int twl_initconnection(TW_Device_Extension *tw_dev, int message_credits,
988 u32 set_features, unsigned short current_fw_srl,
989 unsigned short current_fw_arch_id,
990 unsigned short current_fw_branch,
991 unsigned short current_fw_build,
992 unsigned short *fw_on_ctlr_srl,
993 unsigned short *fw_on_ctlr_arch_id,
994 unsigned short *fw_on_ctlr_branch,
995 unsigned short *fw_on_ctlr_build,
996 u32 *init_connect_result)
998 TW_Command_Full *full_command_packet;
999 TW_Initconnect *tw_initconnect;
1000 int request_id = 0, retval = 1;
1002 /* Initialize InitConnection command packet */
1003 full_command_packet = tw_dev->command_packet_virt[request_id];
1004 memset(full_command_packet, 0, sizeof(TW_Command_Full));
1005 full_command_packet->header.header_desc.size_header = 128;
1007 tw_initconnect = (TW_Initconnect *)&full_command_packet->command.oldcommand;
1008 tw_initconnect->opcode__reserved = TW_OPRES_IN(0, TW_OP_INIT_CONNECTION);
1009 tw_initconnect->request_id = request_id;
1010 tw_initconnect->message_credits = cpu_to_le16(message_credits);
1011 tw_initconnect->features = set_features;
1013 /* Turn on 64-bit sgl support if we need to */
1014 tw_initconnect->features |= sizeof(dma_addr_t) > 4 ? 1 : 0;
1016 tw_initconnect->features = cpu_to_le32(tw_initconnect->features);
1018 if (set_features & TW_EXTENDED_INIT_CONNECT) {
1019 tw_initconnect->size = TW_INIT_COMMAND_PACKET_SIZE_EXTENDED;
1020 tw_initconnect->fw_srl = cpu_to_le16(current_fw_srl);
1021 tw_initconnect->fw_arch_id = cpu_to_le16(current_fw_arch_id);
1022 tw_initconnect->fw_branch = cpu_to_le16(current_fw_branch);
1023 tw_initconnect->fw_build = cpu_to_le16(current_fw_build);
1024 } else
1025 tw_initconnect->size = TW_INIT_COMMAND_PACKET_SIZE;
1027 /* Send command packet to the board */
1028 twl_post_command_packet(tw_dev, request_id);
1030 /* Poll for completion */
1031 if (twl_poll_response(tw_dev, request_id, 30)) {
1032 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x8, "No valid response during init connection");
1033 } else {
1034 if (set_features & TW_EXTENDED_INIT_CONNECT) {
1035 *fw_on_ctlr_srl = le16_to_cpu(tw_initconnect->fw_srl);
1036 *fw_on_ctlr_arch_id = le16_to_cpu(tw_initconnect->fw_arch_id);
1037 *fw_on_ctlr_branch = le16_to_cpu(tw_initconnect->fw_branch);
1038 *fw_on_ctlr_build = le16_to_cpu(tw_initconnect->fw_build);
1039 *init_connect_result = le32_to_cpu(tw_initconnect->result);
1041 retval = 0;
1044 tw_dev->posted_request_count--;
1045 tw_dev->state[request_id] = TW_S_INITIAL;
1047 return retval;
1048 } /* End twl_initconnection() */
1050 /* This function will initialize the fields of a device extension */
1051 static int twl_initialize_device_extension(TW_Device_Extension *tw_dev)
1053 int i, retval = 1;
1055 /* Initialize command packet buffers */
1056 if (twl_allocate_memory(tw_dev, sizeof(TW_Command_Full), 0)) {
1057 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x9, "Command packet memory allocation failed");
1058 goto out;
1061 /* Initialize generic buffer */
1062 if (twl_allocate_memory(tw_dev, TW_SECTOR_SIZE, 1)) {
1063 TW_PRINTK(tw_dev->host, TW_DRIVER, 0xa, "Generic memory allocation failed");
1064 goto out;
1067 /* Allocate sense buffers */
1068 if (twl_allocate_memory(tw_dev, sizeof(TW_Command_Apache_Header), 2)) {
1069 TW_PRINTK(tw_dev->host, TW_DRIVER, 0xb, "Sense buffer allocation failed");
1070 goto out;
1073 /* Allocate event info space */
1074 tw_dev->event_queue[0] = kcalloc(TW_Q_LENGTH, sizeof(TW_Event), GFP_KERNEL);
1075 if (!tw_dev->event_queue[0]) {
1076 TW_PRINTK(tw_dev->host, TW_DRIVER, 0xc, "Event info memory allocation failed");
1077 goto out;
1080 for (i = 0; i < TW_Q_LENGTH; i++) {
1081 tw_dev->event_queue[i] = (TW_Event *)((unsigned char *)tw_dev->event_queue[0] + (i * sizeof(TW_Event)));
1082 tw_dev->free_queue[i] = i;
1083 tw_dev->state[i] = TW_S_INITIAL;
1086 tw_dev->free_head = TW_Q_START;
1087 tw_dev->free_tail = TW_Q_START;
1088 tw_dev->error_sequence_id = 1;
1089 tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE;
1091 mutex_init(&tw_dev->ioctl_lock);
1092 init_waitqueue_head(&tw_dev->ioctl_wqueue);
1094 retval = 0;
1095 out:
1096 return retval;
1097 } /* End twl_initialize_device_extension() */
1099 /* This function will handle attention interrupts */
1100 static int twl_handle_attention_interrupt(TW_Device_Extension *tw_dev)
1102 int retval = 1;
1103 u32 request_id, doorbell;
1105 /* Read doorbell status */
1106 doorbell = readl(TWL_HOBDB_REG_ADDR(tw_dev));
1108 /* Check for controller errors */
1109 if (doorbell & TWL_DOORBELL_CONTROLLER_ERROR) {
1110 TW_PRINTK(tw_dev->host, TW_DRIVER, 0xd, "Microcontroller Error: clearing");
1111 goto out;
1114 /* Check if we need to perform an AEN drain */
1115 if (doorbell & TWL_DOORBELL_ATTENTION_INTERRUPT) {
1116 if (!(test_and_set_bit(TW_IN_ATTENTION_LOOP, &tw_dev->flags))) {
1117 twl_get_request_id(tw_dev, &request_id);
1118 if (twl_aen_read_queue(tw_dev, request_id)) {
1119 tw_dev->state[request_id] = TW_S_COMPLETED;
1120 twl_free_request_id(tw_dev, request_id);
1121 clear_bit(TW_IN_ATTENTION_LOOP, &tw_dev->flags);
1126 retval = 0;
1127 out:
1128 /* Clear doorbell interrupt */
1129 TWL_CLEAR_DB_INTERRUPT(tw_dev);
1131 /* Make sure the clear was flushed by reading it back */
1132 readl(TWL_HOBDBC_REG_ADDR(tw_dev));
1134 return retval;
1135 } /* End twl_handle_attention_interrupt() */
1137 /* Interrupt service routine */
1138 static irqreturn_t twl_interrupt(int irq, void *dev_instance)
1140 TW_Device_Extension *tw_dev = (TW_Device_Extension *)dev_instance;
1141 int i, handled = 0, error = 0;
1142 dma_addr_t mfa = 0;
1143 u32 reg, regl, regh, response, request_id = 0;
1144 struct scsi_cmnd *cmd;
1145 TW_Command_Full *full_command_packet;
1147 spin_lock(tw_dev->host->host_lock);
1149 /* Read host interrupt status */
1150 reg = readl(TWL_HISTAT_REG_ADDR(tw_dev));
1152 /* Check if this is our interrupt, otherwise bail */
1153 if (!(reg & TWL_HISTATUS_VALID_INTERRUPT))
1154 goto twl_interrupt_bail;
1156 handled = 1;
1158 /* If we are resetting, bail */
1159 if (test_bit(TW_IN_RESET, &tw_dev->flags))
1160 goto twl_interrupt_bail;
1162 /* Attention interrupt */
1163 if (reg & TWL_HISTATUS_ATTENTION_INTERRUPT) {
1164 if (twl_handle_attention_interrupt(tw_dev)) {
1165 TWL_MASK_INTERRUPTS(tw_dev);
1166 goto twl_interrupt_bail;
1170 /* Response interrupt */
1171 while (reg & TWL_HISTATUS_RESPONSE_INTERRUPT) {
1172 if (sizeof(dma_addr_t) > 4) {
1173 regh = readl(TWL_HOBQPH_REG_ADDR(tw_dev));
1174 regl = readl(TWL_HOBQPL_REG_ADDR(tw_dev));
1175 mfa = ((u64)regh << 32) | regl;
1176 } else
1177 mfa = readl(TWL_HOBQPL_REG_ADDR(tw_dev));
1179 error = 0;
1180 response = (u32)mfa;
1182 /* Check for command packet error */
1183 if (!TW_NOTMFA_OUT(response)) {
1184 for (i=0;i<TW_Q_LENGTH;i++) {
1185 if (tw_dev->sense_buffer_phys[i] == mfa) {
1186 request_id = le16_to_cpu(tw_dev->sense_buffer_virt[i]->header_desc.request_id);
1187 if (tw_dev->srb[request_id] != NULL)
1188 error = twl_fill_sense(tw_dev, i, request_id, 1, 1);
1189 else {
1190 /* Skip ioctl error prints */
1191 if (request_id != tw_dev->chrdev_request_id)
1192 error = twl_fill_sense(tw_dev, i, request_id, 0, 1);
1193 else
1194 memcpy(tw_dev->command_packet_virt[request_id], tw_dev->sense_buffer_virt[i], sizeof(TW_Command_Apache_Header));
1197 /* Now re-post the sense buffer */
1198 writel((u32)((u64)tw_dev->sense_buffer_phys[i] >> 32), TWL_HOBQPH_REG_ADDR(tw_dev));
1199 writel((u32)tw_dev->sense_buffer_phys[i], TWL_HOBQPL_REG_ADDR(tw_dev));
1200 break;
1203 } else
1204 request_id = TW_RESID_OUT(response);
1206 full_command_packet = tw_dev->command_packet_virt[request_id];
1208 /* Check for correct state */
1209 if (tw_dev->state[request_id] != TW_S_POSTED) {
1210 if (tw_dev->srb[request_id] != NULL) {
1211 TW_PRINTK(tw_dev->host, TW_DRIVER, 0xe, "Received a request id that wasn't posted");
1212 TWL_MASK_INTERRUPTS(tw_dev);
1213 goto twl_interrupt_bail;
1217 /* Check for internal command completion */
1218 if (tw_dev->srb[request_id] == NULL) {
1219 if (request_id != tw_dev->chrdev_request_id) {
1220 if (twl_aen_complete(tw_dev, request_id))
1221 TW_PRINTK(tw_dev->host, TW_DRIVER, 0xf, "Error completing AEN during attention interrupt");
1222 } else {
1223 tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE;
1224 wake_up(&tw_dev->ioctl_wqueue);
1226 } else {
1227 cmd = tw_dev->srb[request_id];
1229 if (!error)
1230 cmd->result = (DID_OK << 16);
1232 /* Report residual bytes for single sgl */
1233 if ((scsi_sg_count(cmd) <= 1) && (full_command_packet->command.newcommand.status == 0)) {
1234 if (full_command_packet->command.newcommand.sg_list[0].length < scsi_bufflen(tw_dev->srb[request_id]))
1235 scsi_set_resid(cmd, scsi_bufflen(cmd) - full_command_packet->command.newcommand.sg_list[0].length);
1238 /* Now complete the io */
1239 scsi_dma_unmap(cmd);
1240 cmd->scsi_done(cmd);
1241 tw_dev->state[request_id] = TW_S_COMPLETED;
1242 twl_free_request_id(tw_dev, request_id);
1243 tw_dev->posted_request_count--;
1246 /* Check for another response interrupt */
1247 reg = readl(TWL_HISTAT_REG_ADDR(tw_dev));
1250 twl_interrupt_bail:
1251 spin_unlock(tw_dev->host->host_lock);
1252 return IRQ_RETVAL(handled);
1253 } /* End twl_interrupt() */
1255 /* This function will poll for a register change */
1256 static int twl_poll_register(TW_Device_Extension *tw_dev, void *reg, u32 value, u32 result, int seconds)
1258 unsigned long before;
1259 int retval = 1;
1260 u32 reg_value;
1262 reg_value = readl(reg);
1263 before = jiffies;
1265 while ((reg_value & value) != result) {
1266 reg_value = readl(reg);
1267 if (time_after(jiffies, before + HZ * seconds))
1268 goto out;
1269 msleep(50);
1271 retval = 0;
1272 out:
1273 return retval;
1274 } /* End twl_poll_register() */
1276 /* This function will reset a controller */
1277 static int twl_reset_sequence(TW_Device_Extension *tw_dev, int soft_reset)
1279 int retval = 1;
1280 int i = 0;
1281 u32 status = 0;
1282 unsigned short fw_on_ctlr_srl = 0, fw_on_ctlr_arch_id = 0;
1283 unsigned short fw_on_ctlr_branch = 0, fw_on_ctlr_build = 0;
1284 u32 init_connect_result = 0;
1285 int tries = 0;
1286 int do_soft_reset = soft_reset;
1288 while (tries < TW_MAX_RESET_TRIES) {
1289 /* Do a soft reset if one is needed */
1290 if (do_soft_reset) {
1291 TWL_SOFT_RESET(tw_dev);
1293 /* Make sure controller is in a good state */
1294 if (twl_poll_register(tw_dev, TWL_SCRPD3_REG_ADDR(tw_dev), TWL_CONTROLLER_READY, 0x0, 30)) {
1295 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x10, "Controller never went non-ready during reset sequence");
1296 tries++;
1297 continue;
1299 if (twl_poll_register(tw_dev, TWL_SCRPD3_REG_ADDR(tw_dev), TWL_CONTROLLER_READY, TWL_CONTROLLER_READY, 60)) {
1300 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x11, "Controller not ready during reset sequence");
1301 tries++;
1302 continue;
1306 /* Initconnect */
1307 if (twl_initconnection(tw_dev, TW_INIT_MESSAGE_CREDITS,
1308 TW_EXTENDED_INIT_CONNECT, TW_CURRENT_DRIVER_SRL,
1309 TW_9750_ARCH_ID, TW_CURRENT_DRIVER_BRANCH,
1310 TW_CURRENT_DRIVER_BUILD, &fw_on_ctlr_srl,
1311 &fw_on_ctlr_arch_id, &fw_on_ctlr_branch,
1312 &fw_on_ctlr_build, &init_connect_result)) {
1313 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x12, "Initconnection failed while checking SRL");
1314 do_soft_reset = 1;
1315 tries++;
1316 continue;
1319 /* Load sense buffers */
1320 while (i < TW_Q_LENGTH) {
1321 writel((u32)((u64)tw_dev->sense_buffer_phys[i] >> 32), TWL_HOBQPH_REG_ADDR(tw_dev));
1322 writel((u32)tw_dev->sense_buffer_phys[i], TWL_HOBQPL_REG_ADDR(tw_dev));
1324 /* Check status for over-run after each write */
1325 status = readl(TWL_STATUS_REG_ADDR(tw_dev));
1326 if (!(status & TWL_STATUS_OVERRUN_SUBMIT))
1327 i++;
1330 /* Now check status */
1331 status = readl(TWL_STATUS_REG_ADDR(tw_dev));
1332 if (status) {
1333 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x13, "Bad controller status after loading sense buffers");
1334 do_soft_reset = 1;
1335 tries++;
1336 continue;
1339 /* Drain the AEN queue */
1340 if (twl_aen_drain_queue(tw_dev, soft_reset)) {
1341 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x14, "AEN drain failed during reset sequence");
1342 do_soft_reset = 1;
1343 tries++;
1344 continue;
1347 /* Load rest of compatibility struct */
1348 strncpy(tw_dev->tw_compat_info.driver_version, TW_DRIVER_VERSION, strlen(TW_DRIVER_VERSION));
1349 tw_dev->tw_compat_info.driver_srl_high = TW_CURRENT_DRIVER_SRL;
1350 tw_dev->tw_compat_info.driver_branch_high = TW_CURRENT_DRIVER_BRANCH;
1351 tw_dev->tw_compat_info.driver_build_high = TW_CURRENT_DRIVER_BUILD;
1352 tw_dev->tw_compat_info.driver_srl_low = TW_BASE_FW_SRL;
1353 tw_dev->tw_compat_info.driver_branch_low = TW_BASE_FW_BRANCH;
1354 tw_dev->tw_compat_info.driver_build_low = TW_BASE_FW_BUILD;
1355 tw_dev->tw_compat_info.fw_on_ctlr_srl = fw_on_ctlr_srl;
1356 tw_dev->tw_compat_info.fw_on_ctlr_branch = fw_on_ctlr_branch;
1357 tw_dev->tw_compat_info.fw_on_ctlr_build = fw_on_ctlr_build;
1359 /* If we got here, controller is in a good state */
1360 retval = 0;
1361 goto out;
1363 out:
1364 return retval;
1365 } /* End twl_reset_sequence() */
1367 /* This function will reset a device extension */
1368 static int twl_reset_device_extension(TW_Device_Extension *tw_dev, int ioctl_reset)
1370 int i = 0, retval = 1;
1371 unsigned long flags = 0;
1373 /* Block SCSI requests while we are resetting */
1374 if (ioctl_reset)
1375 scsi_block_requests(tw_dev->host);
1377 set_bit(TW_IN_RESET, &tw_dev->flags);
1378 TWL_MASK_INTERRUPTS(tw_dev);
1379 TWL_CLEAR_DB_INTERRUPT(tw_dev);
1381 spin_lock_irqsave(tw_dev->host->host_lock, flags);
1383 /* Abort all requests that are in progress */
1384 for (i = 0; i < TW_Q_LENGTH; i++) {
1385 if ((tw_dev->state[i] != TW_S_FINISHED) &&
1386 (tw_dev->state[i] != TW_S_INITIAL) &&
1387 (tw_dev->state[i] != TW_S_COMPLETED)) {
1388 struct scsi_cmnd *cmd = tw_dev->srb[i];
1390 if (cmd) {
1391 cmd->result = (DID_RESET << 16);
1392 scsi_dma_unmap(cmd);
1393 cmd->scsi_done(cmd);
1398 /* Reset queues and counts */
1399 for (i = 0; i < TW_Q_LENGTH; i++) {
1400 tw_dev->free_queue[i] = i;
1401 tw_dev->state[i] = TW_S_INITIAL;
1403 tw_dev->free_head = TW_Q_START;
1404 tw_dev->free_tail = TW_Q_START;
1405 tw_dev->posted_request_count = 0;
1407 spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
1409 if (twl_reset_sequence(tw_dev, 1))
1410 goto out;
1412 TWL_UNMASK_INTERRUPTS(tw_dev);
1414 clear_bit(TW_IN_RESET, &tw_dev->flags);
1415 tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE;
1417 retval = 0;
1418 out:
1419 if (ioctl_reset)
1420 scsi_unblock_requests(tw_dev->host);
1421 return retval;
1422 } /* End twl_reset_device_extension() */
1424 /* This funciton returns unit geometry in cylinders/heads/sectors */
1425 static int twl_scsi_biosparam(struct scsi_device *sdev, struct block_device *bdev, sector_t capacity, int geom[])
1427 int heads, sectors;
1428 TW_Device_Extension *tw_dev;
1430 tw_dev = (TW_Device_Extension *)sdev->host->hostdata;
1432 if (capacity >= 0x200000) {
1433 heads = 255;
1434 sectors = 63;
1435 } else {
1436 heads = 64;
1437 sectors = 32;
1440 geom[0] = heads;
1441 geom[1] = sectors;
1442 geom[2] = sector_div(capacity, heads * sectors); /* cylinders */
1444 return 0;
1445 } /* End twl_scsi_biosparam() */
1447 /* This is the new scsi eh reset function */
1448 static int twl_scsi_eh_reset(struct scsi_cmnd *SCpnt)
1450 TW_Device_Extension *tw_dev = NULL;
1451 int retval = FAILED;
1453 tw_dev = (TW_Device_Extension *)SCpnt->device->host->hostdata;
1455 tw_dev->num_resets++;
1457 sdev_printk(KERN_WARNING, SCpnt->device,
1458 "WARNING: (0x%02X:0x%04X): Command (0x%x) timed out, resetting card.\n",
1459 TW_DRIVER, 0x2c, SCpnt->cmnd[0]);
1461 /* Make sure we are not issuing an ioctl or resetting from ioctl */
1462 mutex_lock(&tw_dev->ioctl_lock);
1464 /* Now reset the card and some of the device extension data */
1465 if (twl_reset_device_extension(tw_dev, 0)) {
1466 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x15, "Controller reset failed during scsi host reset");
1467 goto out;
1470 retval = SUCCESS;
1471 out:
1472 mutex_unlock(&tw_dev->ioctl_lock);
1473 return retval;
1474 } /* End twl_scsi_eh_reset() */
1476 /* This is the main scsi queue function to handle scsi opcodes */
1477 static int twl_scsi_queue_lck(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
1479 int request_id, retval;
1480 TW_Device_Extension *tw_dev = (TW_Device_Extension *)SCpnt->device->host->hostdata;
1482 /* If we are resetting due to timed out ioctl, report as busy */
1483 if (test_bit(TW_IN_RESET, &tw_dev->flags)) {
1484 retval = SCSI_MLQUEUE_HOST_BUSY;
1485 goto out;
1488 /* Save done function into scsi_cmnd struct */
1489 SCpnt->scsi_done = done;
1491 /* Get a free request id */
1492 twl_get_request_id(tw_dev, &request_id);
1494 /* Save the scsi command for use by the ISR */
1495 tw_dev->srb[request_id] = SCpnt;
1497 retval = twl_scsiop_execute_scsi(tw_dev, request_id, NULL, 0, NULL);
1498 if (retval) {
1499 tw_dev->state[request_id] = TW_S_COMPLETED;
1500 twl_free_request_id(tw_dev, request_id);
1501 SCpnt->result = (DID_ERROR << 16);
1502 done(SCpnt);
1503 retval = 0;
1505 out:
1506 return retval;
1507 } /* End twl_scsi_queue() */
1509 static DEF_SCSI_QCMD(twl_scsi_queue)
1511 /* This function tells the controller to shut down */
1512 static void __twl_shutdown(TW_Device_Extension *tw_dev)
1514 /* Disable interrupts */
1515 TWL_MASK_INTERRUPTS(tw_dev);
1517 /* Free up the IRQ */
1518 free_irq(tw_dev->tw_pci_dev->irq, tw_dev);
1520 printk(KERN_WARNING "3w-sas: Shutting down host %d.\n", tw_dev->host->host_no);
1522 /* Tell the card we are shutting down */
1523 if (twl_initconnection(tw_dev, 1, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL)) {
1524 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x16, "Connection shutdown failed");
1525 } else {
1526 printk(KERN_WARNING "3w-sas: Shutdown complete.\n");
1529 /* Clear doorbell interrupt just before exit */
1530 TWL_CLEAR_DB_INTERRUPT(tw_dev);
1531 } /* End __twl_shutdown() */
1533 /* Wrapper for __twl_shutdown */
1534 static void twl_shutdown(struct pci_dev *pdev)
1536 struct Scsi_Host *host = pci_get_drvdata(pdev);
1537 TW_Device_Extension *tw_dev;
1539 if (!host)
1540 return;
1542 tw_dev = (TW_Device_Extension *)host->hostdata;
1544 if (tw_dev->online)
1545 __twl_shutdown(tw_dev);
1546 } /* End twl_shutdown() */
1548 /* This function configures unit settings when a unit is coming on-line */
1549 static int twl_slave_configure(struct scsi_device *sdev)
1551 /* Force 60 second timeout */
1552 blk_queue_rq_timeout(sdev->request_queue, 60 * HZ);
1554 return 0;
1555 } /* End twl_slave_configure() */
1557 /* scsi_host_template initializer */
1558 static struct scsi_host_template driver_template = {
1559 .module = THIS_MODULE,
1560 .name = "3w-sas",
1561 .queuecommand = twl_scsi_queue,
1562 .eh_host_reset_handler = twl_scsi_eh_reset,
1563 .bios_param = twl_scsi_biosparam,
1564 .change_queue_depth = twl_change_queue_depth,
1565 .can_queue = TW_Q_LENGTH-2,
1566 .slave_configure = twl_slave_configure,
1567 .this_id = -1,
1568 .sg_tablesize = TW_LIBERATOR_MAX_SGL_LENGTH,
1569 .max_sectors = TW_MAX_SECTORS,
1570 .cmd_per_lun = TW_MAX_CMDS_PER_LUN,
1571 .use_clustering = ENABLE_CLUSTERING,
1572 .shost_attrs = twl_host_attrs,
1573 .emulated = 1,
1574 .no_write_same = 1,
1577 /* This function will probe and initialize a card */
1578 static int twl_probe(struct pci_dev *pdev, const struct pci_device_id *dev_id)
1580 struct Scsi_Host *host = NULL;
1581 TW_Device_Extension *tw_dev;
1582 int retval = -ENODEV;
1583 int *ptr_phycount, phycount=0;
1585 retval = pci_enable_device(pdev);
1586 if (retval) {
1587 TW_PRINTK(host, TW_DRIVER, 0x17, "Failed to enable pci device");
1588 goto out_disable_device;
1591 pci_set_master(pdev);
1592 pci_try_set_mwi(pdev);
1594 if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64))
1595 || pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)))
1596 if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32))
1597 || pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) {
1598 TW_PRINTK(host, TW_DRIVER, 0x18, "Failed to set dma mask");
1599 retval = -ENODEV;
1600 goto out_disable_device;
1603 host = scsi_host_alloc(&driver_template, sizeof(TW_Device_Extension));
1604 if (!host) {
1605 TW_PRINTK(host, TW_DRIVER, 0x19, "Failed to allocate memory for device extension");
1606 retval = -ENOMEM;
1607 goto out_disable_device;
1609 tw_dev = shost_priv(host);
1611 /* Save values to device extension */
1612 tw_dev->host = host;
1613 tw_dev->tw_pci_dev = pdev;
1615 if (twl_initialize_device_extension(tw_dev)) {
1616 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1a, "Failed to initialize device extension");
1617 goto out_free_device_extension;
1620 /* Request IO regions */
1621 retval = pci_request_regions(pdev, "3w-sas");
1622 if (retval) {
1623 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1b, "Failed to get mem region");
1624 goto out_free_device_extension;
1627 /* Save base address, use region 1 */
1628 tw_dev->base_addr = pci_iomap(pdev, 1, 0);
1629 if (!tw_dev->base_addr) {
1630 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1c, "Failed to ioremap");
1631 goto out_release_mem_region;
1634 /* Disable interrupts on the card */
1635 TWL_MASK_INTERRUPTS(tw_dev);
1637 /* Initialize the card */
1638 if (twl_reset_sequence(tw_dev, 0)) {
1639 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1d, "Controller reset failed during probe");
1640 goto out_iounmap;
1643 /* Set host specific parameters */
1644 host->max_id = TW_MAX_UNITS;
1645 host->max_cmd_len = TW_MAX_CDB_LEN;
1646 host->max_lun = TW_MAX_LUNS;
1647 host->max_channel = 0;
1649 /* Register the card with the kernel SCSI layer */
1650 retval = scsi_add_host(host, &pdev->dev);
1651 if (retval) {
1652 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1e, "scsi add host failed");
1653 goto out_iounmap;
1656 pci_set_drvdata(pdev, host);
1658 printk(KERN_WARNING "3w-sas: scsi%d: Found an LSI 3ware %s Controller at 0x%llx, IRQ: %d.\n",
1659 host->host_no,
1660 (char *)twl_get_param(tw_dev, 1, TW_VERSION_TABLE,
1661 TW_PARAM_MODEL, TW_PARAM_MODEL_LENGTH),
1662 (u64)pci_resource_start(pdev, 1), pdev->irq);
1664 ptr_phycount = twl_get_param(tw_dev, 2, TW_PARAM_PHY_SUMMARY_TABLE,
1665 TW_PARAM_PHYCOUNT, TW_PARAM_PHYCOUNT_LENGTH);
1666 if (ptr_phycount)
1667 phycount = le32_to_cpu(*(int *)ptr_phycount);
1669 printk(KERN_WARNING "3w-sas: scsi%d: Firmware %s, BIOS %s, Phys: %d.\n",
1670 host->host_no,
1671 (char *)twl_get_param(tw_dev, 1, TW_VERSION_TABLE,
1672 TW_PARAM_FWVER, TW_PARAM_FWVER_LENGTH),
1673 (char *)twl_get_param(tw_dev, 2, TW_VERSION_TABLE,
1674 TW_PARAM_BIOSVER, TW_PARAM_BIOSVER_LENGTH),
1675 phycount);
1677 /* Try to enable MSI */
1678 if (use_msi && !pci_enable_msi(pdev))
1679 set_bit(TW_USING_MSI, &tw_dev->flags);
1681 /* Now setup the interrupt handler */
1682 retval = request_irq(pdev->irq, twl_interrupt, IRQF_SHARED, "3w-sas", tw_dev);
1683 if (retval) {
1684 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1f, "Error requesting IRQ");
1685 goto out_remove_host;
1688 twl_device_extension_list[twl_device_extension_count] = tw_dev;
1689 twl_device_extension_count++;
1691 /* Re-enable interrupts on the card */
1692 TWL_UNMASK_INTERRUPTS(tw_dev);
1694 /* Finally, scan the host */
1695 scsi_scan_host(host);
1697 /* Add sysfs binary files */
1698 if (sysfs_create_bin_file(&host->shost_dev.kobj, &twl_sysfs_aen_read_attr))
1699 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x20, "Failed to create sysfs binary file: 3ware_aen_read");
1700 if (sysfs_create_bin_file(&host->shost_dev.kobj, &twl_sysfs_compat_info_attr))
1701 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x21, "Failed to create sysfs binary file: 3ware_compat_info");
1703 if (twl_major == -1) {
1704 if ((twl_major = register_chrdev (0, "twl", &twl_fops)) < 0)
1705 TW_PRINTK(host, TW_DRIVER, 0x22, "Failed to register character device");
1707 tw_dev->online = 1;
1708 return 0;
1710 out_remove_host:
1711 if (test_bit(TW_USING_MSI, &tw_dev->flags))
1712 pci_disable_msi(pdev);
1713 scsi_remove_host(host);
1714 out_iounmap:
1715 iounmap(tw_dev->base_addr);
1716 out_release_mem_region:
1717 pci_release_regions(pdev);
1718 out_free_device_extension:
1719 twl_free_device_extension(tw_dev);
1720 scsi_host_put(host);
1721 out_disable_device:
1722 pci_disable_device(pdev);
1724 return retval;
1725 } /* End twl_probe() */
1727 /* This function is called to remove a device */
1728 static void twl_remove(struct pci_dev *pdev)
1730 struct Scsi_Host *host = pci_get_drvdata(pdev);
1731 TW_Device_Extension *tw_dev;
1733 if (!host)
1734 return;
1736 tw_dev = (TW_Device_Extension *)host->hostdata;
1738 if (!tw_dev->online)
1739 return;
1741 /* Remove sysfs binary files */
1742 sysfs_remove_bin_file(&host->shost_dev.kobj, &twl_sysfs_aen_read_attr);
1743 sysfs_remove_bin_file(&host->shost_dev.kobj, &twl_sysfs_compat_info_attr);
1745 scsi_remove_host(tw_dev->host);
1747 /* Unregister character device */
1748 if (twl_major >= 0) {
1749 unregister_chrdev(twl_major, "twl");
1750 twl_major = -1;
1753 /* Shutdown the card */
1754 __twl_shutdown(tw_dev);
1756 /* Disable MSI if enabled */
1757 if (test_bit(TW_USING_MSI, &tw_dev->flags))
1758 pci_disable_msi(pdev);
1760 /* Free IO remapping */
1761 iounmap(tw_dev->base_addr);
1763 /* Free up the mem region */
1764 pci_release_regions(pdev);
1766 /* Free up device extension resources */
1767 twl_free_device_extension(tw_dev);
1769 scsi_host_put(tw_dev->host);
1770 pci_disable_device(pdev);
1771 twl_device_extension_count--;
1772 } /* End twl_remove() */
1774 #ifdef CONFIG_PM
1775 /* This function is called on PCI suspend */
1776 static int twl_suspend(struct pci_dev *pdev, pm_message_t state)
1778 struct Scsi_Host *host = pci_get_drvdata(pdev);
1779 TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata;
1781 printk(KERN_WARNING "3w-sas: Suspending host %d.\n", tw_dev->host->host_no);
1782 /* Disable interrupts */
1783 TWL_MASK_INTERRUPTS(tw_dev);
1785 free_irq(tw_dev->tw_pci_dev->irq, tw_dev);
1787 /* Tell the card we are shutting down */
1788 if (twl_initconnection(tw_dev, 1, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL)) {
1789 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x23, "Connection shutdown failed during suspend");
1790 } else {
1791 printk(KERN_WARNING "3w-sas: Suspend complete.\n");
1794 /* Clear doorbell interrupt */
1795 TWL_CLEAR_DB_INTERRUPT(tw_dev);
1797 pci_save_state(pdev);
1798 pci_disable_device(pdev);
1799 pci_set_power_state(pdev, pci_choose_state(pdev, state));
1801 return 0;
1802 } /* End twl_suspend() */
1804 /* This function is called on PCI resume */
1805 static int twl_resume(struct pci_dev *pdev)
1807 int retval = 0;
1808 struct Scsi_Host *host = pci_get_drvdata(pdev);
1809 TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata;
1811 printk(KERN_WARNING "3w-sas: Resuming host %d.\n", tw_dev->host->host_no);
1812 pci_set_power_state(pdev, PCI_D0);
1813 pci_enable_wake(pdev, PCI_D0, 0);
1814 pci_restore_state(pdev);
1816 retval = pci_enable_device(pdev);
1817 if (retval) {
1818 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x24, "Enable device failed during resume");
1819 return retval;
1822 pci_set_master(pdev);
1823 pci_try_set_mwi(pdev);
1825 if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64))
1826 || pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)))
1827 if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32))
1828 || pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) {
1829 TW_PRINTK(host, TW_DRIVER, 0x25, "Failed to set dma mask during resume");
1830 retval = -ENODEV;
1831 goto out_disable_device;
1834 /* Initialize the card */
1835 if (twl_reset_sequence(tw_dev, 0)) {
1836 retval = -ENODEV;
1837 goto out_disable_device;
1840 /* Now setup the interrupt handler */
1841 retval = request_irq(pdev->irq, twl_interrupt, IRQF_SHARED, "3w-sas", tw_dev);
1842 if (retval) {
1843 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x26, "Error requesting IRQ during resume");
1844 retval = -ENODEV;
1845 goto out_disable_device;
1848 /* Now enable MSI if enabled */
1849 if (test_bit(TW_USING_MSI, &tw_dev->flags))
1850 pci_enable_msi(pdev);
1852 /* Re-enable interrupts on the card */
1853 TWL_UNMASK_INTERRUPTS(tw_dev);
1855 printk(KERN_WARNING "3w-sas: Resume complete.\n");
1856 return 0;
1858 out_disable_device:
1859 scsi_remove_host(host);
1860 pci_disable_device(pdev);
1862 return retval;
1863 } /* End twl_resume() */
1864 #endif
1866 /* PCI Devices supported by this driver */
1867 static struct pci_device_id twl_pci_tbl[] = {
1868 { PCI_VDEVICE(3WARE, PCI_DEVICE_ID_3WARE_9750) },
1871 MODULE_DEVICE_TABLE(pci, twl_pci_tbl);
1873 /* pci_driver initializer */
1874 static struct pci_driver twl_driver = {
1875 .name = "3w-sas",
1876 .id_table = twl_pci_tbl,
1877 .probe = twl_probe,
1878 .remove = twl_remove,
1879 #ifdef CONFIG_PM
1880 .suspend = twl_suspend,
1881 .resume = twl_resume,
1882 #endif
1883 .shutdown = twl_shutdown
1886 /* This function is called on driver initialization */
1887 static int __init twl_init(void)
1889 printk(KERN_INFO "LSI 3ware SAS/SATA-RAID Controller device driver for Linux v%s.\n", TW_DRIVER_VERSION);
1891 return pci_register_driver(&twl_driver);
1892 } /* End twl_init() */
1894 /* This function is called on driver exit */
1895 static void __exit twl_exit(void)
1897 pci_unregister_driver(&twl_driver);
1898 } /* End twl_exit() */
1900 module_init(twl_init);
1901 module_exit(twl_exit);