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