Version:  2.0.40 2.2.26 2.4.37 3.13 3.14 3.15 3.16 3.17 3.18 3.19 4.0 4.1 4.2 4.3 4.4 4.5 4.6 4.7 4.8 4.9 4.10

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

This page was automatically generated by LXR 0.3.1 (source).  •  Linux is a registered trademark of Linus Torvalds  •  Contact us