i40e: fix proc/int descriptions
[linux-2.6/btrfs-unstable.git] / drivers / scsi / 3w-sas.c
blob2361772d590966abf6f618d2e1228b0f3d424ebc
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 /* stats sysfs attribute initializer */
195 static struct device_attribute twl_host_stats_attr = {
196 .attr = {
197 .name = "3ware_stats",
198 .mode = S_IRUGO,
200 .show = twl_show_stats
203 /* Host attributes initializer */
204 static struct device_attribute *twl_host_attrs[] = {
205 &twl_host_stats_attr,
206 NULL,
209 /* This function will look up an AEN severity string */
210 static char *twl_aen_severity_lookup(unsigned char severity_code)
212 char *retval = NULL;
214 if ((severity_code < (unsigned char) TW_AEN_SEVERITY_ERROR) ||
215 (severity_code > (unsigned char) TW_AEN_SEVERITY_DEBUG))
216 goto out;
218 retval = twl_aen_severity_table[severity_code];
219 out:
220 return retval;
221 } /* End twl_aen_severity_lookup() */
223 /* This function will queue an event */
224 static void twl_aen_queue_event(TW_Device_Extension *tw_dev, TW_Command_Apache_Header *header)
226 u32 local_time;
227 struct timeval time;
228 TW_Event *event;
229 unsigned short aen;
230 char host[16];
231 char *error_str;
233 tw_dev->aen_count++;
235 /* Fill out event info */
236 event = tw_dev->event_queue[tw_dev->error_index];
238 host[0] = '\0';
239 if (tw_dev->host)
240 sprintf(host, " scsi%d:", tw_dev->host->host_no);
242 aen = le16_to_cpu(header->status_block.error);
243 memset(event, 0, sizeof(TW_Event));
245 event->severity = TW_SEV_OUT(header->status_block.severity__reserved);
246 do_gettimeofday(&time);
247 local_time = (u32)(time.tv_sec - (sys_tz.tz_minuteswest * 60));
248 event->time_stamp_sec = local_time;
249 event->aen_code = aen;
250 event->retrieved = TW_AEN_NOT_RETRIEVED;
251 event->sequence_id = tw_dev->error_sequence_id;
252 tw_dev->error_sequence_id++;
254 /* Check for embedded error string */
255 error_str = &(header->err_specific_desc[strlen(header->err_specific_desc)+1]);
257 header->err_specific_desc[sizeof(header->err_specific_desc) - 1] = '\0';
258 event->parameter_len = strlen(header->err_specific_desc);
259 memcpy(event->parameter_data, header->err_specific_desc, event->parameter_len + 1 + strlen(error_str));
260 if (event->severity != TW_AEN_SEVERITY_DEBUG)
261 printk(KERN_WARNING "3w-sas:%s AEN: %s (0x%02X:0x%04X): %s:%s.\n",
262 host,
263 twl_aen_severity_lookup(TW_SEV_OUT(header->status_block.severity__reserved)),
264 TW_MESSAGE_SOURCE_CONTROLLER_EVENT, aen, error_str,
265 header->err_specific_desc);
266 else
267 tw_dev->aen_count--;
269 tw_dev->error_index = (tw_dev->error_index + 1 ) % TW_Q_LENGTH;
270 } /* End twl_aen_queue_event() */
272 /* This function will attempt to post a command packet to the board */
273 static int twl_post_command_packet(TW_Device_Extension *tw_dev, int request_id)
275 dma_addr_t command_que_value;
277 command_que_value = tw_dev->command_packet_phys[request_id];
278 command_que_value += TW_COMMAND_OFFSET;
280 /* First write upper 4 bytes */
281 writel((u32)((u64)command_que_value >> 32), TWL_HIBQPH_REG_ADDR(tw_dev));
282 /* Then the lower 4 bytes */
283 writel((u32)(command_que_value | TWL_PULL_MODE), TWL_HIBQPL_REG_ADDR(tw_dev));
285 tw_dev->state[request_id] = TW_S_POSTED;
286 tw_dev->posted_request_count++;
287 if (tw_dev->posted_request_count > tw_dev->max_posted_request_count)
288 tw_dev->max_posted_request_count = tw_dev->posted_request_count;
290 return 0;
291 } /* End twl_post_command_packet() */
293 /* This function will perform a pci-dma mapping for a scatter gather list */
294 static int twl_map_scsi_sg_data(TW_Device_Extension *tw_dev, int request_id)
296 int use_sg;
297 struct scsi_cmnd *cmd = tw_dev->srb[request_id];
299 use_sg = scsi_dma_map(cmd);
300 if (!use_sg)
301 return 0;
302 else if (use_sg < 0) {
303 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1, "Failed to map scatter gather list");
304 return 0;
307 cmd->SCp.phase = TW_PHASE_SGLIST;
308 cmd->SCp.have_data_in = use_sg;
310 return use_sg;
311 } /* End twl_map_scsi_sg_data() */
313 /* This function hands scsi cdb's to the firmware */
314 static int twl_scsiop_execute_scsi(TW_Device_Extension *tw_dev, int request_id, char *cdb, int use_sg, TW_SG_Entry_ISO *sglistarg)
316 TW_Command_Full *full_command_packet;
317 TW_Command_Apache *command_packet;
318 int i, sg_count;
319 struct scsi_cmnd *srb = NULL;
320 struct scatterlist *sglist = NULL, *sg;
321 int retval = 1;
323 if (tw_dev->srb[request_id]) {
324 srb = tw_dev->srb[request_id];
325 if (scsi_sglist(srb))
326 sglist = scsi_sglist(srb);
329 /* Initialize command packet */
330 full_command_packet = tw_dev->command_packet_virt[request_id];
331 full_command_packet->header.header_desc.size_header = 128;
332 full_command_packet->header.status_block.error = 0;
333 full_command_packet->header.status_block.severity__reserved = 0;
335 command_packet = &full_command_packet->command.newcommand;
336 command_packet->status = 0;
337 command_packet->opcode__reserved = TW_OPRES_IN(0, TW_OP_EXECUTE_SCSI);
339 /* We forced 16 byte cdb use earlier */
340 if (!cdb)
341 memcpy(command_packet->cdb, srb->cmnd, TW_MAX_CDB_LEN);
342 else
343 memcpy(command_packet->cdb, cdb, TW_MAX_CDB_LEN);
345 if (srb) {
346 command_packet->unit = srb->device->id;
347 command_packet->request_id__lunl =
348 cpu_to_le16(TW_REQ_LUN_IN(srb->device->lun, request_id));
349 } else {
350 command_packet->request_id__lunl =
351 cpu_to_le16(TW_REQ_LUN_IN(0, request_id));
352 command_packet->unit = 0;
355 command_packet->sgl_offset = 16;
357 if (!sglistarg) {
358 /* Map sglist from scsi layer to cmd packet */
359 if (scsi_sg_count(srb)) {
360 sg_count = twl_map_scsi_sg_data(tw_dev, request_id);
361 if (sg_count == 0)
362 goto out;
364 scsi_for_each_sg(srb, sg, sg_count, i) {
365 command_packet->sg_list[i].address = TW_CPU_TO_SGL(sg_dma_address(sg));
366 command_packet->sg_list[i].length = TW_CPU_TO_SGL(sg_dma_len(sg));
368 command_packet->sgl_entries__lunh = cpu_to_le16(TW_REQ_LUN_IN((srb->device->lun >> 4), scsi_sg_count(tw_dev->srb[request_id])));
370 } else {
371 /* Internal cdb post */
372 for (i = 0; i < use_sg; i++) {
373 command_packet->sg_list[i].address = TW_CPU_TO_SGL(sglistarg[i].address);
374 command_packet->sg_list[i].length = TW_CPU_TO_SGL(sglistarg[i].length);
376 command_packet->sgl_entries__lunh = cpu_to_le16(TW_REQ_LUN_IN(0, use_sg));
379 /* Update some stats */
380 if (srb) {
381 tw_dev->sector_count = scsi_bufflen(srb) / 512;
382 if (tw_dev->sector_count > tw_dev->max_sector_count)
383 tw_dev->max_sector_count = tw_dev->sector_count;
384 tw_dev->sgl_entries = scsi_sg_count(srb);
385 if (tw_dev->sgl_entries > tw_dev->max_sgl_entries)
386 tw_dev->max_sgl_entries = tw_dev->sgl_entries;
389 /* Now post the command to the board */
390 retval = twl_post_command_packet(tw_dev, request_id);
392 out:
393 return retval;
394 } /* End twl_scsiop_execute_scsi() */
396 /* This function will read the aen queue from the isr */
397 static int twl_aen_read_queue(TW_Device_Extension *tw_dev, int request_id)
399 char cdb[TW_MAX_CDB_LEN];
400 TW_SG_Entry_ISO sglist[1];
401 TW_Command_Full *full_command_packet;
402 int retval = 1;
404 full_command_packet = tw_dev->command_packet_virt[request_id];
405 memset(full_command_packet, 0, sizeof(TW_Command_Full));
407 /* Initialize cdb */
408 memset(&cdb, 0, TW_MAX_CDB_LEN);
409 cdb[0] = REQUEST_SENSE; /* opcode */
410 cdb[4] = TW_ALLOCATION_LENGTH; /* allocation length */
412 /* Initialize sglist */
413 memset(&sglist, 0, sizeof(TW_SG_Entry_ISO));
414 sglist[0].length = TW_SECTOR_SIZE;
415 sglist[0].address = tw_dev->generic_buffer_phys[request_id];
417 /* Mark internal command */
418 tw_dev->srb[request_id] = NULL;
420 /* Now post the command packet */
421 if (twl_scsiop_execute_scsi(tw_dev, request_id, cdb, 1, sglist)) {
422 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x2, "Post failed while reading AEN queue");
423 goto out;
425 retval = 0;
426 out:
427 return retval;
428 } /* End twl_aen_read_queue() */
430 /* This function will sync firmware time with the host time */
431 static void twl_aen_sync_time(TW_Device_Extension *tw_dev, int request_id)
433 u32 schedulertime;
434 struct timeval utc;
435 TW_Command_Full *full_command_packet;
436 TW_Command *command_packet;
437 TW_Param_Apache *param;
438 u32 local_time;
440 /* Fill out the command packet */
441 full_command_packet = tw_dev->command_packet_virt[request_id];
442 memset(full_command_packet, 0, sizeof(TW_Command_Full));
443 command_packet = &full_command_packet->command.oldcommand;
444 command_packet->opcode__sgloffset = TW_OPSGL_IN(2, TW_OP_SET_PARAM);
445 command_packet->request_id = request_id;
446 command_packet->byte8_offset.param.sgl[0].address = TW_CPU_TO_SGL(tw_dev->generic_buffer_phys[request_id]);
447 command_packet->byte8_offset.param.sgl[0].length = TW_CPU_TO_SGL(TW_SECTOR_SIZE);
448 command_packet->size = TW_COMMAND_SIZE;
449 command_packet->byte6_offset.parameter_count = cpu_to_le16(1);
451 /* Setup the param */
452 param = (TW_Param_Apache *)tw_dev->generic_buffer_virt[request_id];
453 memset(param, 0, TW_SECTOR_SIZE);
454 param->table_id = cpu_to_le16(TW_TIMEKEEP_TABLE | 0x8000); /* Controller time keep table */
455 param->parameter_id = cpu_to_le16(0x3); /* SchedulerTime */
456 param->parameter_size_bytes = cpu_to_le16(4);
458 /* Convert system time in UTC to local time seconds since last
459 Sunday 12:00AM */
460 do_gettimeofday(&utc);
461 local_time = (u32)(utc.tv_sec - (sys_tz.tz_minuteswest * 60));
462 schedulertime = local_time - (3 * 86400);
463 schedulertime = cpu_to_le32(schedulertime % 604800);
465 memcpy(param->data, &schedulertime, sizeof(u32));
467 /* Mark internal command */
468 tw_dev->srb[request_id] = NULL;
470 /* Now post the command */
471 twl_post_command_packet(tw_dev, request_id);
472 } /* End twl_aen_sync_time() */
474 /* This function will assign an available request id */
475 static void twl_get_request_id(TW_Device_Extension *tw_dev, int *request_id)
477 *request_id = tw_dev->free_queue[tw_dev->free_head];
478 tw_dev->free_head = (tw_dev->free_head + 1) % TW_Q_LENGTH;
479 tw_dev->state[*request_id] = TW_S_STARTED;
480 } /* End twl_get_request_id() */
482 /* This function will free a request id */
483 static void twl_free_request_id(TW_Device_Extension *tw_dev, int request_id)
485 tw_dev->free_queue[tw_dev->free_tail] = request_id;
486 tw_dev->state[request_id] = TW_S_FINISHED;
487 tw_dev->free_tail = (tw_dev->free_tail + 1) % TW_Q_LENGTH;
488 } /* End twl_free_request_id() */
490 /* This function will complete an aen request from the isr */
491 static int twl_aen_complete(TW_Device_Extension *tw_dev, int request_id)
493 TW_Command_Full *full_command_packet;
494 TW_Command *command_packet;
495 TW_Command_Apache_Header *header;
496 unsigned short aen;
497 int retval = 1;
499 header = (TW_Command_Apache_Header *)tw_dev->generic_buffer_virt[request_id];
500 tw_dev->posted_request_count--;
501 aen = le16_to_cpu(header->status_block.error);
502 full_command_packet = tw_dev->command_packet_virt[request_id];
503 command_packet = &full_command_packet->command.oldcommand;
505 /* First check for internal completion of set param for time sync */
506 if (TW_OP_OUT(command_packet->opcode__sgloffset) == TW_OP_SET_PARAM) {
507 /* Keep reading the queue in case there are more aen's */
508 if (twl_aen_read_queue(tw_dev, request_id))
509 goto out2;
510 else {
511 retval = 0;
512 goto out;
516 switch (aen) {
517 case TW_AEN_QUEUE_EMPTY:
518 /* Quit reading the queue if this is the last one */
519 break;
520 case TW_AEN_SYNC_TIME_WITH_HOST:
521 twl_aen_sync_time(tw_dev, request_id);
522 retval = 0;
523 goto out;
524 default:
525 twl_aen_queue_event(tw_dev, header);
527 /* If there are more aen's, keep reading the queue */
528 if (twl_aen_read_queue(tw_dev, request_id))
529 goto out2;
530 else {
531 retval = 0;
532 goto out;
535 retval = 0;
536 out2:
537 tw_dev->state[request_id] = TW_S_COMPLETED;
538 twl_free_request_id(tw_dev, request_id);
539 clear_bit(TW_IN_ATTENTION_LOOP, &tw_dev->flags);
540 out:
541 return retval;
542 } /* End twl_aen_complete() */
544 /* This function will poll for a response */
545 static int twl_poll_response(TW_Device_Extension *tw_dev, int request_id, int seconds)
547 unsigned long before;
548 dma_addr_t mfa;
549 u32 regh, regl;
550 u32 response;
551 int retval = 1;
552 int found = 0;
554 before = jiffies;
556 while (!found) {
557 if (sizeof(dma_addr_t) > 4) {
558 regh = readl(TWL_HOBQPH_REG_ADDR(tw_dev));
559 regl = readl(TWL_HOBQPL_REG_ADDR(tw_dev));
560 mfa = ((u64)regh << 32) | regl;
561 } else
562 mfa = readl(TWL_HOBQPL_REG_ADDR(tw_dev));
564 response = (u32)mfa;
566 if (TW_RESID_OUT(response) == request_id)
567 found = 1;
569 if (time_after(jiffies, before + HZ * seconds))
570 goto out;
572 msleep(50);
574 retval = 0;
575 out:
576 return retval;
577 } /* End twl_poll_response() */
579 /* This function will drain the aen queue */
580 static int twl_aen_drain_queue(TW_Device_Extension *tw_dev, int no_check_reset)
582 int request_id = 0;
583 char cdb[TW_MAX_CDB_LEN];
584 TW_SG_Entry_ISO sglist[1];
585 int finished = 0, count = 0;
586 TW_Command_Full *full_command_packet;
587 TW_Command_Apache_Header *header;
588 unsigned short aen;
589 int first_reset = 0, queue = 0, retval = 1;
591 if (no_check_reset)
592 first_reset = 0;
593 else
594 first_reset = 1;
596 full_command_packet = tw_dev->command_packet_virt[request_id];
597 memset(full_command_packet, 0, sizeof(TW_Command_Full));
599 /* Initialize cdb */
600 memset(&cdb, 0, TW_MAX_CDB_LEN);
601 cdb[0] = REQUEST_SENSE; /* opcode */
602 cdb[4] = TW_ALLOCATION_LENGTH; /* allocation length */
604 /* Initialize sglist */
605 memset(&sglist, 0, sizeof(TW_SG_Entry_ISO));
606 sglist[0].length = TW_SECTOR_SIZE;
607 sglist[0].address = tw_dev->generic_buffer_phys[request_id];
609 /* Mark internal command */
610 tw_dev->srb[request_id] = NULL;
612 do {
613 /* Send command to the board */
614 if (twl_scsiop_execute_scsi(tw_dev, request_id, cdb, 1, sglist)) {
615 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x3, "Error posting request sense");
616 goto out;
619 /* Now poll for completion */
620 if (twl_poll_response(tw_dev, request_id, 30)) {
621 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x4, "No valid response while draining AEN queue");
622 tw_dev->posted_request_count--;
623 goto out;
626 tw_dev->posted_request_count--;
627 header = (TW_Command_Apache_Header *)tw_dev->generic_buffer_virt[request_id];
628 aen = le16_to_cpu(header->status_block.error);
629 queue = 0;
630 count++;
632 switch (aen) {
633 case TW_AEN_QUEUE_EMPTY:
634 if (first_reset != 1)
635 goto out;
636 else
637 finished = 1;
638 break;
639 case TW_AEN_SOFT_RESET:
640 if (first_reset == 0)
641 first_reset = 1;
642 else
643 queue = 1;
644 break;
645 case TW_AEN_SYNC_TIME_WITH_HOST:
646 break;
647 default:
648 queue = 1;
651 /* Now queue an event info */
652 if (queue)
653 twl_aen_queue_event(tw_dev, header);
654 } while ((finished == 0) && (count < TW_MAX_AEN_DRAIN));
656 if (count == TW_MAX_AEN_DRAIN)
657 goto out;
659 retval = 0;
660 out:
661 tw_dev->state[request_id] = TW_S_INITIAL;
662 return retval;
663 } /* End twl_aen_drain_queue() */
665 /* This function will allocate memory and check if it is correctly aligned */
666 static int twl_allocate_memory(TW_Device_Extension *tw_dev, int size, int which)
668 int i;
669 dma_addr_t dma_handle;
670 unsigned long *cpu_addr;
671 int retval = 1;
673 cpu_addr = pci_zalloc_consistent(tw_dev->tw_pci_dev, size * TW_Q_LENGTH,
674 &dma_handle);
675 if (!cpu_addr) {
676 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x5, "Memory allocation failed");
677 goto out;
680 for (i = 0; i < TW_Q_LENGTH; i++) {
681 switch(which) {
682 case 0:
683 tw_dev->command_packet_phys[i] = dma_handle+(i*size);
684 tw_dev->command_packet_virt[i] = (TW_Command_Full *)((unsigned char *)cpu_addr + (i*size));
685 break;
686 case 1:
687 tw_dev->generic_buffer_phys[i] = dma_handle+(i*size);
688 tw_dev->generic_buffer_virt[i] = (unsigned long *)((unsigned char *)cpu_addr + (i*size));
689 break;
690 case 2:
691 tw_dev->sense_buffer_phys[i] = dma_handle+(i*size);
692 tw_dev->sense_buffer_virt[i] = (TW_Command_Apache_Header *)((unsigned char *)cpu_addr + (i*size));
693 break;
696 retval = 0;
697 out:
698 return retval;
699 } /* End twl_allocate_memory() */
701 /* This function will load the request id and various sgls for ioctls */
702 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)
704 TW_Command *oldcommand;
705 TW_Command_Apache *newcommand;
706 TW_SG_Entry_ISO *sgl;
707 unsigned int pae = 0;
709 if ((sizeof(long) < 8) && (sizeof(dma_addr_t) > 4))
710 pae = 1;
712 if (TW_OP_OUT(full_command_packet->command.newcommand.opcode__reserved) == TW_OP_EXECUTE_SCSI) {
713 newcommand = &full_command_packet->command.newcommand;
714 newcommand->request_id__lunl =
715 cpu_to_le16(TW_REQ_LUN_IN(TW_LUN_OUT(newcommand->request_id__lunl), request_id));
716 if (length) {
717 newcommand->sg_list[0].address = TW_CPU_TO_SGL(dma_handle + sizeof(TW_Ioctl_Buf_Apache) - 1);
718 newcommand->sg_list[0].length = TW_CPU_TO_SGL(length);
720 newcommand->sgl_entries__lunh =
721 cpu_to_le16(TW_REQ_LUN_IN(TW_LUN_OUT(newcommand->sgl_entries__lunh), length ? 1 : 0));
722 } else {
723 oldcommand = &full_command_packet->command.oldcommand;
724 oldcommand->request_id = request_id;
726 if (TW_SGL_OUT(oldcommand->opcode__sgloffset)) {
727 /* Load the sg list */
728 sgl = (TW_SG_Entry_ISO *)((u32 *)oldcommand+oldcommand->size - (sizeof(TW_SG_Entry_ISO)/4) + pae + (sizeof(dma_addr_t) > 4 ? 1 : 0));
729 sgl->address = TW_CPU_TO_SGL(dma_handle + sizeof(TW_Ioctl_Buf_Apache) - 1);
730 sgl->length = TW_CPU_TO_SGL(length);
731 oldcommand->size += pae;
732 oldcommand->size += sizeof(dma_addr_t) > 4 ? 1 : 0;
735 } /* End twl_load_sgl() */
737 /* This function handles ioctl for the character device
738 This interface is used by smartmontools open source software */
739 static long twl_chrdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
741 long timeout;
742 unsigned long *cpu_addr, data_buffer_length_adjusted = 0, flags = 0;
743 dma_addr_t dma_handle;
744 int request_id = 0;
745 TW_Ioctl_Driver_Command driver_command;
746 struct inode *inode = file_inode(file);
747 TW_Ioctl_Buf_Apache *tw_ioctl;
748 TW_Command_Full *full_command_packet;
749 TW_Device_Extension *tw_dev = twl_device_extension_list[iminor(inode)];
750 int retval = -EFAULT;
751 void __user *argp = (void __user *)arg;
753 mutex_lock(&twl_chrdev_mutex);
755 /* Only let one of these through at a time */
756 if (mutex_lock_interruptible(&tw_dev->ioctl_lock)) {
757 retval = -EINTR;
758 goto out;
761 /* First copy down the driver command */
762 if (copy_from_user(&driver_command, argp, sizeof(TW_Ioctl_Driver_Command)))
763 goto out2;
765 /* Check data buffer size */
766 if (driver_command.buffer_length > TW_MAX_SECTORS * 2048) {
767 retval = -EINVAL;
768 goto out2;
771 /* Hardware can only do multiple of 512 byte transfers */
772 data_buffer_length_adjusted = (driver_command.buffer_length + 511) & ~511;
774 /* Now allocate ioctl buf memory */
775 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);
776 if (!cpu_addr) {
777 retval = -ENOMEM;
778 goto out2;
781 tw_ioctl = (TW_Ioctl_Buf_Apache *)cpu_addr;
783 /* Now copy down the entire ioctl */
784 if (copy_from_user(tw_ioctl, argp, driver_command.buffer_length + sizeof(TW_Ioctl_Buf_Apache) - 1))
785 goto out3;
787 /* See which ioctl we are doing */
788 switch (cmd) {
789 case TW_IOCTL_FIRMWARE_PASS_THROUGH:
790 spin_lock_irqsave(tw_dev->host->host_lock, flags);
791 twl_get_request_id(tw_dev, &request_id);
793 /* Flag internal command */
794 tw_dev->srb[request_id] = NULL;
796 /* Flag chrdev ioctl */
797 tw_dev->chrdev_request_id = request_id;
799 full_command_packet = (TW_Command_Full *)&tw_ioctl->firmware_command;
801 /* Load request id and sglist for both command types */
802 twl_load_sgl(tw_dev, full_command_packet, request_id, dma_handle, data_buffer_length_adjusted);
804 memcpy(tw_dev->command_packet_virt[request_id], &(tw_ioctl->firmware_command), sizeof(TW_Command_Full));
806 /* Now post the command packet to the controller */
807 twl_post_command_packet(tw_dev, request_id);
808 spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
810 timeout = TW_IOCTL_CHRDEV_TIMEOUT*HZ;
812 /* Now wait for command to complete */
813 timeout = wait_event_timeout(tw_dev->ioctl_wqueue, tw_dev->chrdev_request_id == TW_IOCTL_CHRDEV_FREE, timeout);
815 /* We timed out, and didn't get an interrupt */
816 if (tw_dev->chrdev_request_id != TW_IOCTL_CHRDEV_FREE) {
817 /* Now we need to reset the board */
818 printk(KERN_WARNING "3w-sas: scsi%d: WARNING: (0x%02X:0x%04X): Character ioctl (0x%x) timed out, resetting card.\n",
819 tw_dev->host->host_no, TW_DRIVER, 0x6,
820 cmd);
821 retval = -EIO;
822 twl_reset_device_extension(tw_dev, 1);
823 goto out3;
826 /* Now copy in the command packet response */
827 memcpy(&(tw_ioctl->firmware_command), tw_dev->command_packet_virt[request_id], sizeof(TW_Command_Full));
829 /* Now complete the io */
830 spin_lock_irqsave(tw_dev->host->host_lock, flags);
831 tw_dev->posted_request_count--;
832 tw_dev->state[request_id] = TW_S_COMPLETED;
833 twl_free_request_id(tw_dev, request_id);
834 spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
835 break;
836 default:
837 retval = -ENOTTY;
838 goto out3;
841 /* Now copy the entire response to userspace */
842 if (copy_to_user(argp, tw_ioctl, sizeof(TW_Ioctl_Buf_Apache) + driver_command.buffer_length - 1) == 0)
843 retval = 0;
844 out3:
845 /* Now free ioctl buf memory */
846 dma_free_coherent(&tw_dev->tw_pci_dev->dev, data_buffer_length_adjusted+sizeof(TW_Ioctl_Buf_Apache) - 1, cpu_addr, dma_handle);
847 out2:
848 mutex_unlock(&tw_dev->ioctl_lock);
849 out:
850 mutex_unlock(&twl_chrdev_mutex);
851 return retval;
852 } /* End twl_chrdev_ioctl() */
854 /* This function handles open for the character device */
855 static int twl_chrdev_open(struct inode *inode, struct file *file)
857 unsigned int minor_number;
858 int retval = -ENODEV;
860 if (!capable(CAP_SYS_ADMIN)) {
861 retval = -EACCES;
862 goto out;
865 minor_number = iminor(inode);
866 if (minor_number >= twl_device_extension_count)
867 goto out;
868 retval = 0;
869 out:
870 return retval;
871 } /* End twl_chrdev_open() */
873 /* File operations struct for character device */
874 static const struct file_operations twl_fops = {
875 .owner = THIS_MODULE,
876 .unlocked_ioctl = twl_chrdev_ioctl,
877 .open = twl_chrdev_open,
878 .release = NULL,
879 .llseek = noop_llseek,
882 /* This function passes sense data from firmware to scsi layer */
883 static int twl_fill_sense(TW_Device_Extension *tw_dev, int i, int request_id, int copy_sense, int print_host)
885 TW_Command_Apache_Header *header;
886 TW_Command_Full *full_command_packet;
887 unsigned short error;
888 char *error_str;
889 int retval = 1;
891 header = tw_dev->sense_buffer_virt[i];
892 full_command_packet = tw_dev->command_packet_virt[request_id];
894 /* Get embedded firmware error string */
895 error_str = &(header->err_specific_desc[strlen(header->err_specific_desc) + 1]);
897 /* Don't print error for Logical unit not supported during rollcall */
898 error = le16_to_cpu(header->status_block.error);
899 if ((error != TW_ERROR_LOGICAL_UNIT_NOT_SUPPORTED) && (error != TW_ERROR_UNIT_OFFLINE) && (error != TW_ERROR_INVALID_FIELD_IN_CDB)) {
900 if (print_host)
901 printk(KERN_WARNING "3w-sas: scsi%d: ERROR: (0x%02X:0x%04X): %s:%s.\n",
902 tw_dev->host->host_no,
903 TW_MESSAGE_SOURCE_CONTROLLER_ERROR,
904 header->status_block.error,
905 error_str,
906 header->err_specific_desc);
907 else
908 printk(KERN_WARNING "3w-sas: ERROR: (0x%02X:0x%04X): %s:%s.\n",
909 TW_MESSAGE_SOURCE_CONTROLLER_ERROR,
910 header->status_block.error,
911 error_str,
912 header->err_specific_desc);
915 if (copy_sense) {
916 memcpy(tw_dev->srb[request_id]->sense_buffer, header->sense_data, TW_SENSE_DATA_LENGTH);
917 tw_dev->srb[request_id]->result = (full_command_packet->command.newcommand.status << 1);
918 goto out;
920 out:
921 return retval;
922 } /* End twl_fill_sense() */
924 /* This function will free up device extension resources */
925 static void twl_free_device_extension(TW_Device_Extension *tw_dev)
927 if (tw_dev->command_packet_virt[0])
928 pci_free_consistent(tw_dev->tw_pci_dev,
929 sizeof(TW_Command_Full)*TW_Q_LENGTH,
930 tw_dev->command_packet_virt[0],
931 tw_dev->command_packet_phys[0]);
933 if (tw_dev->generic_buffer_virt[0])
934 pci_free_consistent(tw_dev->tw_pci_dev,
935 TW_SECTOR_SIZE*TW_Q_LENGTH,
936 tw_dev->generic_buffer_virt[0],
937 tw_dev->generic_buffer_phys[0]);
939 if (tw_dev->sense_buffer_virt[0])
940 pci_free_consistent(tw_dev->tw_pci_dev,
941 sizeof(TW_Command_Apache_Header)*
942 TW_Q_LENGTH,
943 tw_dev->sense_buffer_virt[0],
944 tw_dev->sense_buffer_phys[0]);
946 kfree(tw_dev->event_queue[0]);
947 } /* End twl_free_device_extension() */
949 /* This function will get parameter table entries from the firmware */
950 static void *twl_get_param(TW_Device_Extension *tw_dev, int request_id, int table_id, int parameter_id, int parameter_size_bytes)
952 TW_Command_Full *full_command_packet;
953 TW_Command *command_packet;
954 TW_Param_Apache *param;
955 void *retval = NULL;
957 /* Setup the command packet */
958 full_command_packet = tw_dev->command_packet_virt[request_id];
959 memset(full_command_packet, 0, sizeof(TW_Command_Full));
960 command_packet = &full_command_packet->command.oldcommand;
962 command_packet->opcode__sgloffset = TW_OPSGL_IN(2, TW_OP_GET_PARAM);
963 command_packet->size = TW_COMMAND_SIZE;
964 command_packet->request_id = request_id;
965 command_packet->byte6_offset.block_count = cpu_to_le16(1);
967 /* Now setup the param */
968 param = (TW_Param_Apache *)tw_dev->generic_buffer_virt[request_id];
969 memset(param, 0, TW_SECTOR_SIZE);
970 param->table_id = cpu_to_le16(table_id | 0x8000);
971 param->parameter_id = cpu_to_le16(parameter_id);
972 param->parameter_size_bytes = cpu_to_le16(parameter_size_bytes);
974 command_packet->byte8_offset.param.sgl[0].address = TW_CPU_TO_SGL(tw_dev->generic_buffer_phys[request_id]);
975 command_packet->byte8_offset.param.sgl[0].length = TW_CPU_TO_SGL(TW_SECTOR_SIZE);
977 /* Post the command packet to the board */
978 twl_post_command_packet(tw_dev, request_id);
980 /* Poll for completion */
981 if (twl_poll_response(tw_dev, request_id, 30))
982 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x7, "No valid response during get param")
983 else
984 retval = (void *)&(param->data[0]);
986 tw_dev->posted_request_count--;
987 tw_dev->state[request_id] = TW_S_INITIAL;
989 return retval;
990 } /* End twl_get_param() */
992 /* This function will send an initconnection command to controller */
993 static int twl_initconnection(TW_Device_Extension *tw_dev, int message_credits,
994 u32 set_features, unsigned short current_fw_srl,
995 unsigned short current_fw_arch_id,
996 unsigned short current_fw_branch,
997 unsigned short current_fw_build,
998 unsigned short *fw_on_ctlr_srl,
999 unsigned short *fw_on_ctlr_arch_id,
1000 unsigned short *fw_on_ctlr_branch,
1001 unsigned short *fw_on_ctlr_build,
1002 u32 *init_connect_result)
1004 TW_Command_Full *full_command_packet;
1005 TW_Initconnect *tw_initconnect;
1006 int request_id = 0, retval = 1;
1008 /* Initialize InitConnection command packet */
1009 full_command_packet = tw_dev->command_packet_virt[request_id];
1010 memset(full_command_packet, 0, sizeof(TW_Command_Full));
1011 full_command_packet->header.header_desc.size_header = 128;
1013 tw_initconnect = (TW_Initconnect *)&full_command_packet->command.oldcommand;
1014 tw_initconnect->opcode__reserved = TW_OPRES_IN(0, TW_OP_INIT_CONNECTION);
1015 tw_initconnect->request_id = request_id;
1016 tw_initconnect->message_credits = cpu_to_le16(message_credits);
1017 tw_initconnect->features = set_features;
1019 /* Turn on 64-bit sgl support if we need to */
1020 tw_initconnect->features |= sizeof(dma_addr_t) > 4 ? 1 : 0;
1022 tw_initconnect->features = cpu_to_le32(tw_initconnect->features);
1024 if (set_features & TW_EXTENDED_INIT_CONNECT) {
1025 tw_initconnect->size = TW_INIT_COMMAND_PACKET_SIZE_EXTENDED;
1026 tw_initconnect->fw_srl = cpu_to_le16(current_fw_srl);
1027 tw_initconnect->fw_arch_id = cpu_to_le16(current_fw_arch_id);
1028 tw_initconnect->fw_branch = cpu_to_le16(current_fw_branch);
1029 tw_initconnect->fw_build = cpu_to_le16(current_fw_build);
1030 } else
1031 tw_initconnect->size = TW_INIT_COMMAND_PACKET_SIZE;
1033 /* Send command packet to the board */
1034 twl_post_command_packet(tw_dev, request_id);
1036 /* Poll for completion */
1037 if (twl_poll_response(tw_dev, request_id, 30)) {
1038 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x8, "No valid response during init connection");
1039 } else {
1040 if (set_features & TW_EXTENDED_INIT_CONNECT) {
1041 *fw_on_ctlr_srl = le16_to_cpu(tw_initconnect->fw_srl);
1042 *fw_on_ctlr_arch_id = le16_to_cpu(tw_initconnect->fw_arch_id);
1043 *fw_on_ctlr_branch = le16_to_cpu(tw_initconnect->fw_branch);
1044 *fw_on_ctlr_build = le16_to_cpu(tw_initconnect->fw_build);
1045 *init_connect_result = le32_to_cpu(tw_initconnect->result);
1047 retval = 0;
1050 tw_dev->posted_request_count--;
1051 tw_dev->state[request_id] = TW_S_INITIAL;
1053 return retval;
1054 } /* End twl_initconnection() */
1056 /* This function will initialize the fields of a device extension */
1057 static int twl_initialize_device_extension(TW_Device_Extension *tw_dev)
1059 int i, retval = 1;
1061 /* Initialize command packet buffers */
1062 if (twl_allocate_memory(tw_dev, sizeof(TW_Command_Full), 0)) {
1063 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x9, "Command packet memory allocation failed");
1064 goto out;
1067 /* Initialize generic buffer */
1068 if (twl_allocate_memory(tw_dev, TW_SECTOR_SIZE, 1)) {
1069 TW_PRINTK(tw_dev->host, TW_DRIVER, 0xa, "Generic memory allocation failed");
1070 goto out;
1073 /* Allocate sense buffers */
1074 if (twl_allocate_memory(tw_dev, sizeof(TW_Command_Apache_Header), 2)) {
1075 TW_PRINTK(tw_dev->host, TW_DRIVER, 0xb, "Sense buffer allocation failed");
1076 goto out;
1079 /* Allocate event info space */
1080 tw_dev->event_queue[0] = kcalloc(TW_Q_LENGTH, sizeof(TW_Event), GFP_KERNEL);
1081 if (!tw_dev->event_queue[0]) {
1082 TW_PRINTK(tw_dev->host, TW_DRIVER, 0xc, "Event info memory allocation failed");
1083 goto out;
1086 for (i = 0; i < TW_Q_LENGTH; i++) {
1087 tw_dev->event_queue[i] = (TW_Event *)((unsigned char *)tw_dev->event_queue[0] + (i * sizeof(TW_Event)));
1088 tw_dev->free_queue[i] = i;
1089 tw_dev->state[i] = TW_S_INITIAL;
1092 tw_dev->free_head = TW_Q_START;
1093 tw_dev->free_tail = TW_Q_START;
1094 tw_dev->error_sequence_id = 1;
1095 tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE;
1097 mutex_init(&tw_dev->ioctl_lock);
1098 init_waitqueue_head(&tw_dev->ioctl_wqueue);
1100 retval = 0;
1101 out:
1102 return retval;
1103 } /* End twl_initialize_device_extension() */
1105 /* This function will perform a pci-dma unmap */
1106 static void twl_unmap_scsi_data(TW_Device_Extension *tw_dev, int request_id)
1108 struct scsi_cmnd *cmd = tw_dev->srb[request_id];
1110 if (cmd->SCp.phase == TW_PHASE_SGLIST)
1111 scsi_dma_unmap(cmd);
1112 } /* End twl_unmap_scsi_data() */
1114 /* This function will handle attention interrupts */
1115 static int twl_handle_attention_interrupt(TW_Device_Extension *tw_dev)
1117 int retval = 1;
1118 u32 request_id, doorbell;
1120 /* Read doorbell status */
1121 doorbell = readl(TWL_HOBDB_REG_ADDR(tw_dev));
1123 /* Check for controller errors */
1124 if (doorbell & TWL_DOORBELL_CONTROLLER_ERROR) {
1125 TW_PRINTK(tw_dev->host, TW_DRIVER, 0xd, "Microcontroller Error: clearing");
1126 goto out;
1129 /* Check if we need to perform an AEN drain */
1130 if (doorbell & TWL_DOORBELL_ATTENTION_INTERRUPT) {
1131 if (!(test_and_set_bit(TW_IN_ATTENTION_LOOP, &tw_dev->flags))) {
1132 twl_get_request_id(tw_dev, &request_id);
1133 if (twl_aen_read_queue(tw_dev, request_id)) {
1134 tw_dev->state[request_id] = TW_S_COMPLETED;
1135 twl_free_request_id(tw_dev, request_id);
1136 clear_bit(TW_IN_ATTENTION_LOOP, &tw_dev->flags);
1141 retval = 0;
1142 out:
1143 /* Clear doorbell interrupt */
1144 TWL_CLEAR_DB_INTERRUPT(tw_dev);
1146 /* Make sure the clear was flushed by reading it back */
1147 readl(TWL_HOBDBC_REG_ADDR(tw_dev));
1149 return retval;
1150 } /* End twl_handle_attention_interrupt() */
1152 /* Interrupt service routine */
1153 static irqreturn_t twl_interrupt(int irq, void *dev_instance)
1155 TW_Device_Extension *tw_dev = (TW_Device_Extension *)dev_instance;
1156 int i, handled = 0, error = 0;
1157 dma_addr_t mfa = 0;
1158 u32 reg, regl, regh, response, request_id = 0;
1159 struct scsi_cmnd *cmd;
1160 TW_Command_Full *full_command_packet;
1162 spin_lock(tw_dev->host->host_lock);
1164 /* Read host interrupt status */
1165 reg = readl(TWL_HISTAT_REG_ADDR(tw_dev));
1167 /* Check if this is our interrupt, otherwise bail */
1168 if (!(reg & TWL_HISTATUS_VALID_INTERRUPT))
1169 goto twl_interrupt_bail;
1171 handled = 1;
1173 /* If we are resetting, bail */
1174 if (test_bit(TW_IN_RESET, &tw_dev->flags))
1175 goto twl_interrupt_bail;
1177 /* Attention interrupt */
1178 if (reg & TWL_HISTATUS_ATTENTION_INTERRUPT) {
1179 if (twl_handle_attention_interrupt(tw_dev)) {
1180 TWL_MASK_INTERRUPTS(tw_dev);
1181 goto twl_interrupt_bail;
1185 /* Response interrupt */
1186 while (reg & TWL_HISTATUS_RESPONSE_INTERRUPT) {
1187 if (sizeof(dma_addr_t) > 4) {
1188 regh = readl(TWL_HOBQPH_REG_ADDR(tw_dev));
1189 regl = readl(TWL_HOBQPL_REG_ADDR(tw_dev));
1190 mfa = ((u64)regh << 32) | regl;
1191 } else
1192 mfa = readl(TWL_HOBQPL_REG_ADDR(tw_dev));
1194 error = 0;
1195 response = (u32)mfa;
1197 /* Check for command packet error */
1198 if (!TW_NOTMFA_OUT(response)) {
1199 for (i=0;i<TW_Q_LENGTH;i++) {
1200 if (tw_dev->sense_buffer_phys[i] == mfa) {
1201 request_id = le16_to_cpu(tw_dev->sense_buffer_virt[i]->header_desc.request_id);
1202 if (tw_dev->srb[request_id] != NULL)
1203 error = twl_fill_sense(tw_dev, i, request_id, 1, 1);
1204 else {
1205 /* Skip ioctl error prints */
1206 if (request_id != tw_dev->chrdev_request_id)
1207 error = twl_fill_sense(tw_dev, i, request_id, 0, 1);
1208 else
1209 memcpy(tw_dev->command_packet_virt[request_id], tw_dev->sense_buffer_virt[i], sizeof(TW_Command_Apache_Header));
1212 /* Now re-post the sense buffer */
1213 writel((u32)((u64)tw_dev->sense_buffer_phys[i] >> 32), TWL_HOBQPH_REG_ADDR(tw_dev));
1214 writel((u32)tw_dev->sense_buffer_phys[i], TWL_HOBQPL_REG_ADDR(tw_dev));
1215 break;
1218 } else
1219 request_id = TW_RESID_OUT(response);
1221 full_command_packet = tw_dev->command_packet_virt[request_id];
1223 /* Check for correct state */
1224 if (tw_dev->state[request_id] != TW_S_POSTED) {
1225 if (tw_dev->srb[request_id] != NULL) {
1226 TW_PRINTK(tw_dev->host, TW_DRIVER, 0xe, "Received a request id that wasn't posted");
1227 TWL_MASK_INTERRUPTS(tw_dev);
1228 goto twl_interrupt_bail;
1232 /* Check for internal command completion */
1233 if (tw_dev->srb[request_id] == NULL) {
1234 if (request_id != tw_dev->chrdev_request_id) {
1235 if (twl_aen_complete(tw_dev, request_id))
1236 TW_PRINTK(tw_dev->host, TW_DRIVER, 0xf, "Error completing AEN during attention interrupt");
1237 } else {
1238 tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE;
1239 wake_up(&tw_dev->ioctl_wqueue);
1241 } else {
1242 cmd = tw_dev->srb[request_id];
1244 if (!error)
1245 cmd->result = (DID_OK << 16);
1247 /* Report residual bytes for single sgl */
1248 if ((scsi_sg_count(cmd) <= 1) && (full_command_packet->command.newcommand.status == 0)) {
1249 if (full_command_packet->command.newcommand.sg_list[0].length < scsi_bufflen(tw_dev->srb[request_id]))
1250 scsi_set_resid(cmd, scsi_bufflen(cmd) - full_command_packet->command.newcommand.sg_list[0].length);
1253 /* Now complete the io */
1254 tw_dev->state[request_id] = TW_S_COMPLETED;
1255 twl_free_request_id(tw_dev, request_id);
1256 tw_dev->posted_request_count--;
1257 tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
1258 twl_unmap_scsi_data(tw_dev, request_id);
1261 /* Check for another response interrupt */
1262 reg = readl(TWL_HISTAT_REG_ADDR(tw_dev));
1265 twl_interrupt_bail:
1266 spin_unlock(tw_dev->host->host_lock);
1267 return IRQ_RETVAL(handled);
1268 } /* End twl_interrupt() */
1270 /* This function will poll for a register change */
1271 static int twl_poll_register(TW_Device_Extension *tw_dev, void *reg, u32 value, u32 result, int seconds)
1273 unsigned long before;
1274 int retval = 1;
1275 u32 reg_value;
1277 reg_value = readl(reg);
1278 before = jiffies;
1280 while ((reg_value & value) != result) {
1281 reg_value = readl(reg);
1282 if (time_after(jiffies, before + HZ * seconds))
1283 goto out;
1284 msleep(50);
1286 retval = 0;
1287 out:
1288 return retval;
1289 } /* End twl_poll_register() */
1291 /* This function will reset a controller */
1292 static int twl_reset_sequence(TW_Device_Extension *tw_dev, int soft_reset)
1294 int retval = 1;
1295 int i = 0;
1296 u32 status = 0;
1297 unsigned short fw_on_ctlr_srl = 0, fw_on_ctlr_arch_id = 0;
1298 unsigned short fw_on_ctlr_branch = 0, fw_on_ctlr_build = 0;
1299 u32 init_connect_result = 0;
1300 int tries = 0;
1301 int do_soft_reset = soft_reset;
1303 while (tries < TW_MAX_RESET_TRIES) {
1304 /* Do a soft reset if one is needed */
1305 if (do_soft_reset) {
1306 TWL_SOFT_RESET(tw_dev);
1308 /* Make sure controller is in a good state */
1309 if (twl_poll_register(tw_dev, TWL_SCRPD3_REG_ADDR(tw_dev), TWL_CONTROLLER_READY, 0x0, 30)) {
1310 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x10, "Controller never went non-ready during reset sequence");
1311 tries++;
1312 continue;
1314 if (twl_poll_register(tw_dev, TWL_SCRPD3_REG_ADDR(tw_dev), TWL_CONTROLLER_READY, TWL_CONTROLLER_READY, 60)) {
1315 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x11, "Controller not ready during reset sequence");
1316 tries++;
1317 continue;
1321 /* Initconnect */
1322 if (twl_initconnection(tw_dev, TW_INIT_MESSAGE_CREDITS,
1323 TW_EXTENDED_INIT_CONNECT, TW_CURRENT_DRIVER_SRL,
1324 TW_9750_ARCH_ID, TW_CURRENT_DRIVER_BRANCH,
1325 TW_CURRENT_DRIVER_BUILD, &fw_on_ctlr_srl,
1326 &fw_on_ctlr_arch_id, &fw_on_ctlr_branch,
1327 &fw_on_ctlr_build, &init_connect_result)) {
1328 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x12, "Initconnection failed while checking SRL");
1329 do_soft_reset = 1;
1330 tries++;
1331 continue;
1334 /* Load sense buffers */
1335 while (i < TW_Q_LENGTH) {
1336 writel((u32)((u64)tw_dev->sense_buffer_phys[i] >> 32), TWL_HOBQPH_REG_ADDR(tw_dev));
1337 writel((u32)tw_dev->sense_buffer_phys[i], TWL_HOBQPL_REG_ADDR(tw_dev));
1339 /* Check status for over-run after each write */
1340 status = readl(TWL_STATUS_REG_ADDR(tw_dev));
1341 if (!(status & TWL_STATUS_OVERRUN_SUBMIT))
1342 i++;
1345 /* Now check status */
1346 status = readl(TWL_STATUS_REG_ADDR(tw_dev));
1347 if (status) {
1348 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x13, "Bad controller status after loading sense buffers");
1349 do_soft_reset = 1;
1350 tries++;
1351 continue;
1354 /* Drain the AEN queue */
1355 if (twl_aen_drain_queue(tw_dev, soft_reset)) {
1356 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x14, "AEN drain failed during reset sequence");
1357 do_soft_reset = 1;
1358 tries++;
1359 continue;
1362 /* Load rest of compatibility struct */
1363 strncpy(tw_dev->tw_compat_info.driver_version, TW_DRIVER_VERSION, strlen(TW_DRIVER_VERSION));
1364 tw_dev->tw_compat_info.driver_srl_high = TW_CURRENT_DRIVER_SRL;
1365 tw_dev->tw_compat_info.driver_branch_high = TW_CURRENT_DRIVER_BRANCH;
1366 tw_dev->tw_compat_info.driver_build_high = TW_CURRENT_DRIVER_BUILD;
1367 tw_dev->tw_compat_info.driver_srl_low = TW_BASE_FW_SRL;
1368 tw_dev->tw_compat_info.driver_branch_low = TW_BASE_FW_BRANCH;
1369 tw_dev->tw_compat_info.driver_build_low = TW_BASE_FW_BUILD;
1370 tw_dev->tw_compat_info.fw_on_ctlr_srl = fw_on_ctlr_srl;
1371 tw_dev->tw_compat_info.fw_on_ctlr_branch = fw_on_ctlr_branch;
1372 tw_dev->tw_compat_info.fw_on_ctlr_build = fw_on_ctlr_build;
1374 /* If we got here, controller is in a good state */
1375 retval = 0;
1376 goto out;
1378 out:
1379 return retval;
1380 } /* End twl_reset_sequence() */
1382 /* This function will reset a device extension */
1383 static int twl_reset_device_extension(TW_Device_Extension *tw_dev, int ioctl_reset)
1385 int i = 0, retval = 1;
1386 unsigned long flags = 0;
1388 /* Block SCSI requests while we are resetting */
1389 if (ioctl_reset)
1390 scsi_block_requests(tw_dev->host);
1392 set_bit(TW_IN_RESET, &tw_dev->flags);
1393 TWL_MASK_INTERRUPTS(tw_dev);
1394 TWL_CLEAR_DB_INTERRUPT(tw_dev);
1396 spin_lock_irqsave(tw_dev->host->host_lock, flags);
1398 /* Abort all requests that are in progress */
1399 for (i = 0; i < TW_Q_LENGTH; i++) {
1400 if ((tw_dev->state[i] != TW_S_FINISHED) &&
1401 (tw_dev->state[i] != TW_S_INITIAL) &&
1402 (tw_dev->state[i] != TW_S_COMPLETED)) {
1403 if (tw_dev->srb[i]) {
1404 tw_dev->srb[i]->result = (DID_RESET << 16);
1405 tw_dev->srb[i]->scsi_done(tw_dev->srb[i]);
1406 twl_unmap_scsi_data(tw_dev, i);
1411 /* Reset queues and counts */
1412 for (i = 0; i < TW_Q_LENGTH; i++) {
1413 tw_dev->free_queue[i] = i;
1414 tw_dev->state[i] = TW_S_INITIAL;
1416 tw_dev->free_head = TW_Q_START;
1417 tw_dev->free_tail = TW_Q_START;
1418 tw_dev->posted_request_count = 0;
1420 spin_unlock_irqrestore(tw_dev->host->host_lock, flags);
1422 if (twl_reset_sequence(tw_dev, 1))
1423 goto out;
1425 TWL_UNMASK_INTERRUPTS(tw_dev);
1427 clear_bit(TW_IN_RESET, &tw_dev->flags);
1428 tw_dev->chrdev_request_id = TW_IOCTL_CHRDEV_FREE;
1430 retval = 0;
1431 out:
1432 if (ioctl_reset)
1433 scsi_unblock_requests(tw_dev->host);
1434 return retval;
1435 } /* End twl_reset_device_extension() */
1437 /* This funciton returns unit geometry in cylinders/heads/sectors */
1438 static int twl_scsi_biosparam(struct scsi_device *sdev, struct block_device *bdev, sector_t capacity, int geom[])
1440 int heads, sectors;
1441 TW_Device_Extension *tw_dev;
1443 tw_dev = (TW_Device_Extension *)sdev->host->hostdata;
1445 if (capacity >= 0x200000) {
1446 heads = 255;
1447 sectors = 63;
1448 } else {
1449 heads = 64;
1450 sectors = 32;
1453 geom[0] = heads;
1454 geom[1] = sectors;
1455 geom[2] = sector_div(capacity, heads * sectors); /* cylinders */
1457 return 0;
1458 } /* End twl_scsi_biosparam() */
1460 /* This is the new scsi eh reset function */
1461 static int twl_scsi_eh_reset(struct scsi_cmnd *SCpnt)
1463 TW_Device_Extension *tw_dev = NULL;
1464 int retval = FAILED;
1466 tw_dev = (TW_Device_Extension *)SCpnt->device->host->hostdata;
1468 tw_dev->num_resets++;
1470 sdev_printk(KERN_WARNING, SCpnt->device,
1471 "WARNING: (0x%02X:0x%04X): Command (0x%x) timed out, resetting card.\n",
1472 TW_DRIVER, 0x2c, SCpnt->cmnd[0]);
1474 /* Make sure we are not issuing an ioctl or resetting from ioctl */
1475 mutex_lock(&tw_dev->ioctl_lock);
1477 /* Now reset the card and some of the device extension data */
1478 if (twl_reset_device_extension(tw_dev, 0)) {
1479 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x15, "Controller reset failed during scsi host reset");
1480 goto out;
1483 retval = SUCCESS;
1484 out:
1485 mutex_unlock(&tw_dev->ioctl_lock);
1486 return retval;
1487 } /* End twl_scsi_eh_reset() */
1489 /* This is the main scsi queue function to handle scsi opcodes */
1490 static int twl_scsi_queue_lck(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
1492 int request_id, retval;
1493 TW_Device_Extension *tw_dev = (TW_Device_Extension *)SCpnt->device->host->hostdata;
1495 /* If we are resetting due to timed out ioctl, report as busy */
1496 if (test_bit(TW_IN_RESET, &tw_dev->flags)) {
1497 retval = SCSI_MLQUEUE_HOST_BUSY;
1498 goto out;
1501 /* Save done function into scsi_cmnd struct */
1502 SCpnt->scsi_done = done;
1504 /* Get a free request id */
1505 twl_get_request_id(tw_dev, &request_id);
1507 /* Save the scsi command for use by the ISR */
1508 tw_dev->srb[request_id] = SCpnt;
1510 /* Initialize phase to zero */
1511 SCpnt->SCp.phase = TW_PHASE_INITIAL;
1513 retval = twl_scsiop_execute_scsi(tw_dev, request_id, NULL, 0, NULL);
1514 if (retval) {
1515 tw_dev->state[request_id] = TW_S_COMPLETED;
1516 twl_free_request_id(tw_dev, request_id);
1517 SCpnt->result = (DID_ERROR << 16);
1518 done(SCpnt);
1519 retval = 0;
1521 out:
1522 return retval;
1523 } /* End twl_scsi_queue() */
1525 static DEF_SCSI_QCMD(twl_scsi_queue)
1527 /* This function tells the controller to shut down */
1528 static void __twl_shutdown(TW_Device_Extension *tw_dev)
1530 /* Disable interrupts */
1531 TWL_MASK_INTERRUPTS(tw_dev);
1533 /* Free up the IRQ */
1534 free_irq(tw_dev->tw_pci_dev->irq, tw_dev);
1536 printk(KERN_WARNING "3w-sas: Shutting down host %d.\n", tw_dev->host->host_no);
1538 /* Tell the card we are shutting down */
1539 if (twl_initconnection(tw_dev, 1, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL)) {
1540 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x16, "Connection shutdown failed");
1541 } else {
1542 printk(KERN_WARNING "3w-sas: Shutdown complete.\n");
1545 /* Clear doorbell interrupt just before exit */
1546 TWL_CLEAR_DB_INTERRUPT(tw_dev);
1547 } /* End __twl_shutdown() */
1549 /* Wrapper for __twl_shutdown */
1550 static void twl_shutdown(struct pci_dev *pdev)
1552 struct Scsi_Host *host = pci_get_drvdata(pdev);
1553 TW_Device_Extension *tw_dev;
1555 if (!host)
1556 return;
1558 tw_dev = (TW_Device_Extension *)host->hostdata;
1560 if (tw_dev->online)
1561 __twl_shutdown(tw_dev);
1562 } /* End twl_shutdown() */
1564 /* This function configures unit settings when a unit is coming on-line */
1565 static int twl_slave_configure(struct scsi_device *sdev)
1567 /* Force 60 second timeout */
1568 blk_queue_rq_timeout(sdev->request_queue, 60 * HZ);
1570 return 0;
1571 } /* End twl_slave_configure() */
1573 /* scsi_host_template initializer */
1574 static struct scsi_host_template driver_template = {
1575 .module = THIS_MODULE,
1576 .name = "3w-sas",
1577 .queuecommand = twl_scsi_queue,
1578 .eh_host_reset_handler = twl_scsi_eh_reset,
1579 .bios_param = twl_scsi_biosparam,
1580 .change_queue_depth = scsi_change_queue_depth,
1581 .can_queue = TW_Q_LENGTH-2,
1582 .slave_configure = twl_slave_configure,
1583 .this_id = -1,
1584 .sg_tablesize = TW_LIBERATOR_MAX_SGL_LENGTH,
1585 .max_sectors = TW_MAX_SECTORS,
1586 .cmd_per_lun = TW_MAX_CMDS_PER_LUN,
1587 .use_clustering = ENABLE_CLUSTERING,
1588 .shost_attrs = twl_host_attrs,
1589 .emulated = 1,
1590 .no_write_same = 1,
1593 /* This function will probe and initialize a card */
1594 static int twl_probe(struct pci_dev *pdev, const struct pci_device_id *dev_id)
1596 struct Scsi_Host *host = NULL;
1597 TW_Device_Extension *tw_dev;
1598 int retval = -ENODEV;
1599 int *ptr_phycount, phycount=0;
1601 retval = pci_enable_device(pdev);
1602 if (retval) {
1603 TW_PRINTK(host, TW_DRIVER, 0x17, "Failed to enable pci device");
1604 goto out_disable_device;
1607 pci_set_master(pdev);
1608 pci_try_set_mwi(pdev);
1610 if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64))
1611 || pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)))
1612 if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32))
1613 || pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) {
1614 TW_PRINTK(host, TW_DRIVER, 0x18, "Failed to set dma mask");
1615 retval = -ENODEV;
1616 goto out_disable_device;
1619 host = scsi_host_alloc(&driver_template, sizeof(TW_Device_Extension));
1620 if (!host) {
1621 TW_PRINTK(host, TW_DRIVER, 0x19, "Failed to allocate memory for device extension");
1622 retval = -ENOMEM;
1623 goto out_disable_device;
1625 tw_dev = shost_priv(host);
1627 /* Save values to device extension */
1628 tw_dev->host = host;
1629 tw_dev->tw_pci_dev = pdev;
1631 if (twl_initialize_device_extension(tw_dev)) {
1632 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1a, "Failed to initialize device extension");
1633 goto out_free_device_extension;
1636 /* Request IO regions */
1637 retval = pci_request_regions(pdev, "3w-sas");
1638 if (retval) {
1639 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1b, "Failed to get mem region");
1640 goto out_free_device_extension;
1643 /* Save base address, use region 1 */
1644 tw_dev->base_addr = pci_iomap(pdev, 1, 0);
1645 if (!tw_dev->base_addr) {
1646 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1c, "Failed to ioremap");
1647 goto out_release_mem_region;
1650 /* Disable interrupts on the card */
1651 TWL_MASK_INTERRUPTS(tw_dev);
1653 /* Initialize the card */
1654 if (twl_reset_sequence(tw_dev, 0)) {
1655 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1d, "Controller reset failed during probe");
1656 goto out_iounmap;
1659 /* Set host specific parameters */
1660 host->max_id = TW_MAX_UNITS;
1661 host->max_cmd_len = TW_MAX_CDB_LEN;
1662 host->max_lun = TW_MAX_LUNS;
1663 host->max_channel = 0;
1665 /* Register the card with the kernel SCSI layer */
1666 retval = scsi_add_host(host, &pdev->dev);
1667 if (retval) {
1668 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1e, "scsi add host failed");
1669 goto out_iounmap;
1672 pci_set_drvdata(pdev, host);
1674 printk(KERN_WARNING "3w-sas: scsi%d: Found an LSI 3ware %s Controller at 0x%llx, IRQ: %d.\n",
1675 host->host_no,
1676 (char *)twl_get_param(tw_dev, 1, TW_VERSION_TABLE,
1677 TW_PARAM_MODEL, TW_PARAM_MODEL_LENGTH),
1678 (u64)pci_resource_start(pdev, 1), pdev->irq);
1680 ptr_phycount = twl_get_param(tw_dev, 2, TW_PARAM_PHY_SUMMARY_TABLE,
1681 TW_PARAM_PHYCOUNT, TW_PARAM_PHYCOUNT_LENGTH);
1682 if (ptr_phycount)
1683 phycount = le32_to_cpu(*(int *)ptr_phycount);
1685 printk(KERN_WARNING "3w-sas: scsi%d: Firmware %s, BIOS %s, Phys: %d.\n",
1686 host->host_no,
1687 (char *)twl_get_param(tw_dev, 1, TW_VERSION_TABLE,
1688 TW_PARAM_FWVER, TW_PARAM_FWVER_LENGTH),
1689 (char *)twl_get_param(tw_dev, 2, TW_VERSION_TABLE,
1690 TW_PARAM_BIOSVER, TW_PARAM_BIOSVER_LENGTH),
1691 phycount);
1693 /* Try to enable MSI */
1694 if (use_msi && !pci_enable_msi(pdev))
1695 set_bit(TW_USING_MSI, &tw_dev->flags);
1697 /* Now setup the interrupt handler */
1698 retval = request_irq(pdev->irq, twl_interrupt, IRQF_SHARED, "3w-sas", tw_dev);
1699 if (retval) {
1700 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1f, "Error requesting IRQ");
1701 goto out_remove_host;
1704 twl_device_extension_list[twl_device_extension_count] = tw_dev;
1705 twl_device_extension_count++;
1707 /* Re-enable interrupts on the card */
1708 TWL_UNMASK_INTERRUPTS(tw_dev);
1710 /* Finally, scan the host */
1711 scsi_scan_host(host);
1713 /* Add sysfs binary files */
1714 if (sysfs_create_bin_file(&host->shost_dev.kobj, &twl_sysfs_aen_read_attr))
1715 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x20, "Failed to create sysfs binary file: 3ware_aen_read");
1716 if (sysfs_create_bin_file(&host->shost_dev.kobj, &twl_sysfs_compat_info_attr))
1717 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x21, "Failed to create sysfs binary file: 3ware_compat_info");
1719 if (twl_major == -1) {
1720 if ((twl_major = register_chrdev (0, "twl", &twl_fops)) < 0)
1721 TW_PRINTK(host, TW_DRIVER, 0x22, "Failed to register character device");
1723 tw_dev->online = 1;
1724 return 0;
1726 out_remove_host:
1727 if (test_bit(TW_USING_MSI, &tw_dev->flags))
1728 pci_disable_msi(pdev);
1729 scsi_remove_host(host);
1730 out_iounmap:
1731 iounmap(tw_dev->base_addr);
1732 out_release_mem_region:
1733 pci_release_regions(pdev);
1734 out_free_device_extension:
1735 twl_free_device_extension(tw_dev);
1736 scsi_host_put(host);
1737 out_disable_device:
1738 pci_disable_device(pdev);
1740 return retval;
1741 } /* End twl_probe() */
1743 /* This function is called to remove a device */
1744 static void twl_remove(struct pci_dev *pdev)
1746 struct Scsi_Host *host = pci_get_drvdata(pdev);
1747 TW_Device_Extension *tw_dev;
1749 if (!host)
1750 return;
1752 tw_dev = (TW_Device_Extension *)host->hostdata;
1754 if (!tw_dev->online)
1755 return;
1757 /* Remove sysfs binary files */
1758 sysfs_remove_bin_file(&host->shost_dev.kobj, &twl_sysfs_aen_read_attr);
1759 sysfs_remove_bin_file(&host->shost_dev.kobj, &twl_sysfs_compat_info_attr);
1761 scsi_remove_host(tw_dev->host);
1763 /* Unregister character device */
1764 if (twl_major >= 0) {
1765 unregister_chrdev(twl_major, "twl");
1766 twl_major = -1;
1769 /* Shutdown the card */
1770 __twl_shutdown(tw_dev);
1772 /* Disable MSI if enabled */
1773 if (test_bit(TW_USING_MSI, &tw_dev->flags))
1774 pci_disable_msi(pdev);
1776 /* Free IO remapping */
1777 iounmap(tw_dev->base_addr);
1779 /* Free up the mem region */
1780 pci_release_regions(pdev);
1782 /* Free up device extension resources */
1783 twl_free_device_extension(tw_dev);
1785 scsi_host_put(tw_dev->host);
1786 pci_disable_device(pdev);
1787 twl_device_extension_count--;
1788 } /* End twl_remove() */
1790 #ifdef CONFIG_PM
1791 /* This function is called on PCI suspend */
1792 static int twl_suspend(struct pci_dev *pdev, pm_message_t state)
1794 struct Scsi_Host *host = pci_get_drvdata(pdev);
1795 TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata;
1797 printk(KERN_WARNING "3w-sas: Suspending host %d.\n", tw_dev->host->host_no);
1798 /* Disable interrupts */
1799 TWL_MASK_INTERRUPTS(tw_dev);
1801 free_irq(tw_dev->tw_pci_dev->irq, tw_dev);
1803 /* Tell the card we are shutting down */
1804 if (twl_initconnection(tw_dev, 1, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL)) {
1805 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x23, "Connection shutdown failed during suspend");
1806 } else {
1807 printk(KERN_WARNING "3w-sas: Suspend complete.\n");
1810 /* Clear doorbell interrupt */
1811 TWL_CLEAR_DB_INTERRUPT(tw_dev);
1813 pci_save_state(pdev);
1814 pci_disable_device(pdev);
1815 pci_set_power_state(pdev, pci_choose_state(pdev, state));
1817 return 0;
1818 } /* End twl_suspend() */
1820 /* This function is called on PCI resume */
1821 static int twl_resume(struct pci_dev *pdev)
1823 int retval = 0;
1824 struct Scsi_Host *host = pci_get_drvdata(pdev);
1825 TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata;
1827 printk(KERN_WARNING "3w-sas: Resuming host %d.\n", tw_dev->host->host_no);
1828 pci_set_power_state(pdev, PCI_D0);
1829 pci_enable_wake(pdev, PCI_D0, 0);
1830 pci_restore_state(pdev);
1832 retval = pci_enable_device(pdev);
1833 if (retval) {
1834 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x24, "Enable device failed during resume");
1835 return retval;
1838 pci_set_master(pdev);
1839 pci_try_set_mwi(pdev);
1841 if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64))
1842 || pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)))
1843 if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32))
1844 || pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) {
1845 TW_PRINTK(host, TW_DRIVER, 0x25, "Failed to set dma mask during resume");
1846 retval = -ENODEV;
1847 goto out_disable_device;
1850 /* Initialize the card */
1851 if (twl_reset_sequence(tw_dev, 0)) {
1852 retval = -ENODEV;
1853 goto out_disable_device;
1856 /* Now setup the interrupt handler */
1857 retval = request_irq(pdev->irq, twl_interrupt, IRQF_SHARED, "3w-sas", tw_dev);
1858 if (retval) {
1859 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x26, "Error requesting IRQ during resume");
1860 retval = -ENODEV;
1861 goto out_disable_device;
1864 /* Now enable MSI if enabled */
1865 if (test_bit(TW_USING_MSI, &tw_dev->flags))
1866 pci_enable_msi(pdev);
1868 /* Re-enable interrupts on the card */
1869 TWL_UNMASK_INTERRUPTS(tw_dev);
1871 printk(KERN_WARNING "3w-sas: Resume complete.\n");
1872 return 0;
1874 out_disable_device:
1875 scsi_remove_host(host);
1876 pci_disable_device(pdev);
1878 return retval;
1879 } /* End twl_resume() */
1880 #endif
1882 /* PCI Devices supported by this driver */
1883 static struct pci_device_id twl_pci_tbl[] = {
1884 { PCI_VDEVICE(3WARE, PCI_DEVICE_ID_3WARE_9750) },
1887 MODULE_DEVICE_TABLE(pci, twl_pci_tbl);
1889 /* pci_driver initializer */
1890 static struct pci_driver twl_driver = {
1891 .name = "3w-sas",
1892 .id_table = twl_pci_tbl,
1893 .probe = twl_probe,
1894 .remove = twl_remove,
1895 #ifdef CONFIG_PM
1896 .suspend = twl_suspend,
1897 .resume = twl_resume,
1898 #endif
1899 .shutdown = twl_shutdown
1902 /* This function is called on driver initialization */
1903 static int __init twl_init(void)
1905 printk(KERN_INFO "LSI 3ware SAS/SATA-RAID Controller device driver for Linux v%s.\n", TW_DRIVER_VERSION);
1907 return pci_register_driver(&twl_driver);
1908 } /* End twl_init() */
1910 /* This function is called on driver exit */
1911 static void __exit twl_exit(void)
1913 pci_unregister_driver(&twl_driver);
1914 } /* End twl_exit() */
1916 module_init(twl_init);
1917 module_exit(twl_exit);