root/drivers/scsi/3w-sas.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. twl_sysfs_aen_read
  2. twl_sysfs_compat_info
  3. twl_show_stats
  4. twl_aen_severity_lookup
  5. twl_aen_queue_event
  6. twl_post_command_packet
  7. twl_scsiop_execute_scsi
  8. twl_aen_read_queue
  9. twl_aen_sync_time
  10. twl_get_request_id
  11. twl_free_request_id
  12. twl_aen_complete
  13. twl_poll_response
  14. twl_aen_drain_queue
  15. twl_allocate_memory
  16. twl_load_sgl
  17. twl_chrdev_ioctl
  18. twl_chrdev_open
  19. twl_fill_sense
  20. twl_free_device_extension
  21. twl_get_param
  22. twl_initconnection
  23. twl_initialize_device_extension
  24. twl_handle_attention_interrupt
  25. twl_interrupt
  26. twl_poll_register
  27. twl_reset_sequence
  28. twl_reset_device_extension
  29. twl_scsi_biosparam
  30. twl_scsi_eh_reset
  31. twl_scsi_queue_lck
  32. DEF_SCSI_QCMD
  33. twl_shutdown
  34. twl_slave_configure
  35. twl_probe
  36. twl_remove
  37. twl_suspend
  38. twl_resume
  39. twl_init
  40. twl_exit

   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         TW_Event *event;
 225         unsigned short aen;
 226         char host[16];
 227         char *error_str;
 228 
 229         tw_dev->aen_count++;
 230 
 231         /* Fill out event info */
 232         event = tw_dev->event_queue[tw_dev->error_index];
 233 
 234         host[0] = '\0';
 235         if (tw_dev->host)
 236                 sprintf(host, " scsi%d:", tw_dev->host->host_no);
 237 
 238         aen = le16_to_cpu(header->status_block.error);
 239         memset(event, 0, sizeof(TW_Event));
 240 
 241         event->severity = TW_SEV_OUT(header->status_block.severity__reserved);
 242         /* event->time_stamp_sec overflows in y2106 */
 243         local_time = (u32)(ktime_get_real_seconds() - (sys_tz.tz_minuteswest * 60));
 244         event->time_stamp_sec = local_time;
 245         event->aen_code = aen;
 246         event->retrieved = TW_AEN_NOT_RETRIEVED;
 247         event->sequence_id = tw_dev->error_sequence_id;
 248         tw_dev->error_sequence_id++;
 249 
 250         /* Check for embedded error string */
 251         error_str = &(header->err_specific_desc[strlen(header->err_specific_desc)+1]);
 252 
 253         header->err_specific_desc[sizeof(header->err_specific_desc) - 1] = '\0';
 254         event->parameter_len = strlen(header->err_specific_desc);
 255         memcpy(event->parameter_data, header->err_specific_desc, event->parameter_len + 1 + strlen(error_str));
 256         if (event->severity != TW_AEN_SEVERITY_DEBUG)
 257                 printk(KERN_WARNING "3w-sas:%s AEN: %s (0x%02X:0x%04X): %s:%s.\n",
 258                        host,
 259                        twl_aen_severity_lookup(TW_SEV_OUT(header->status_block.severity__reserved)),
 260                        TW_MESSAGE_SOURCE_CONTROLLER_EVENT, aen, error_str,
 261                        header->err_specific_desc);
 262         else
 263                 tw_dev->aen_count--;
 264 
 265         tw_dev->error_index = (tw_dev->error_index + 1 ) % TW_Q_LENGTH;
 266 } /* End twl_aen_queue_event() */
 267 
 268 /* This function will attempt to post a command packet to the board */
 269 static int twl_post_command_packet(TW_Device_Extension *tw_dev, int request_id)
 270 {
 271         dma_addr_t command_que_value;
 272 
 273         command_que_value = tw_dev->command_packet_phys[request_id];
 274         command_que_value += TW_COMMAND_OFFSET;
 275 
 276         /* First write upper 4 bytes */
 277         writel((u32)((u64)command_que_value >> 32), TWL_HIBQPH_REG_ADDR(tw_dev));
 278         /* Then the lower 4 bytes */
 279         writel((u32)(command_que_value | TWL_PULL_MODE), TWL_HIBQPL_REG_ADDR(tw_dev));
 280 
 281         tw_dev->state[request_id] = TW_S_POSTED;
 282         tw_dev->posted_request_count++;
 283         if (tw_dev->posted_request_count > tw_dev->max_posted_request_count)
 284                 tw_dev->max_posted_request_count = tw_dev->posted_request_count;
 285 
 286         return 0;
 287 } /* End twl_post_command_packet() */
 288 
 289 /* This function hands scsi cdb's to the firmware */
 290 static int twl_scsiop_execute_scsi(TW_Device_Extension *tw_dev, int request_id,
 291                                    unsigned char *cdb, int use_sg,
 292                                    TW_SG_Entry_ISO *sglistarg)
 293 {
 294         TW_Command_Full *full_command_packet;
 295         TW_Command_Apache *command_packet;
 296         int i, sg_count;
 297         struct scsi_cmnd *srb = NULL;
 298         struct scatterlist *sglist = NULL, *sg;
 299         int retval = 1;
 300 
 301         if (tw_dev->srb[request_id]) {
 302                 srb = tw_dev->srb[request_id];
 303                 if (scsi_sglist(srb))
 304                         sglist = scsi_sglist(srb);
 305         }
 306 
 307         /* Initialize command packet */
 308         full_command_packet = tw_dev->command_packet_virt[request_id];
 309         full_command_packet->header.header_desc.size_header = 128;
 310         full_command_packet->header.status_block.error = 0;
 311         full_command_packet->header.status_block.severity__reserved = 0;
 312 
 313         command_packet = &full_command_packet->command.newcommand;
 314         command_packet->status = 0;
 315         command_packet->opcode__reserved = TW_OPRES_IN(0, TW_OP_EXECUTE_SCSI);
 316 
 317         /* We forced 16 byte cdb use earlier */
 318         if (!cdb)
 319                 memcpy(command_packet->cdb, srb->cmnd, TW_MAX_CDB_LEN);
 320         else
 321                 memcpy(command_packet->cdb, cdb, TW_MAX_CDB_LEN);
 322 
 323         if (srb) {
 324                 command_packet->unit = srb->device->id;
 325                 command_packet->request_id__lunl =
 326                         cpu_to_le16(TW_REQ_LUN_IN(srb->device->lun, request_id));
 327         } else {
 328                 command_packet->request_id__lunl =
 329                         cpu_to_le16(TW_REQ_LUN_IN(0, request_id));
 330                 command_packet->unit = 0;
 331         }
 332 
 333         command_packet->sgl_offset = 16;
 334 
 335         if (!sglistarg) {
 336                 /* Map sglist from scsi layer to cmd packet */
 337                 if (scsi_sg_count(srb)) {
 338                         sg_count = scsi_dma_map(srb);
 339                         if (sg_count <= 0)
 340                                 goto out;
 341 
 342                         scsi_for_each_sg(srb, sg, sg_count, i) {
 343                                 command_packet->sg_list[i].address = TW_CPU_TO_SGL(sg_dma_address(sg));
 344                                 command_packet->sg_list[i].length = TW_CPU_TO_SGL(sg_dma_len(sg));
 345                         }
 346                         command_packet->sgl_entries__lunh = cpu_to_le16(TW_REQ_LUN_IN((srb->device->lun >> 4), scsi_sg_count(tw_dev->srb[request_id])));
 347                 }
 348         } else {
 349                 /* Internal cdb post */
 350                 for (i = 0; i < use_sg; i++) {
 351                         command_packet->sg_list[i].address = TW_CPU_TO_SGL(sglistarg[i].address);
 352                         command_packet->sg_list[i].length = TW_CPU_TO_SGL(sglistarg[i].length);
 353                 }
 354                 command_packet->sgl_entries__lunh = cpu_to_le16(TW_REQ_LUN_IN(0, use_sg));
 355         }
 356 
 357         /* Update some stats */
 358         if (srb) {
 359                 tw_dev->sector_count = scsi_bufflen(srb) / 512;
 360                 if (tw_dev->sector_count > tw_dev->max_sector_count)
 361                         tw_dev->max_sector_count = tw_dev->sector_count;
 362                 tw_dev->sgl_entries = scsi_sg_count(srb);
 363                 if (tw_dev->sgl_entries > tw_dev->max_sgl_entries)
 364                         tw_dev->max_sgl_entries = tw_dev->sgl_entries;
 365         }
 366 
 367         /* Now post the command to the board */
 368         retval = twl_post_command_packet(tw_dev, request_id);
 369 
 370 out:
 371         return retval;
 372 } /* End twl_scsiop_execute_scsi() */
 373 
 374 /* This function will read the aen queue from the isr */
 375 static int twl_aen_read_queue(TW_Device_Extension *tw_dev, int request_id)
 376 {
 377         unsigned char cdb[TW_MAX_CDB_LEN];
 378         TW_SG_Entry_ISO sglist[1];
 379         TW_Command_Full *full_command_packet;
 380         int retval = 1;
 381 
 382         full_command_packet = tw_dev->command_packet_virt[request_id];
 383         memset(full_command_packet, 0, sizeof(TW_Command_Full));
 384 
 385         /* Initialize cdb */
 386         memset(&cdb, 0, TW_MAX_CDB_LEN);
 387         cdb[0] = REQUEST_SENSE; /* opcode */
 388         cdb[4] = TW_ALLOCATION_LENGTH; /* allocation length */
 389 
 390         /* Initialize sglist */
 391         memset(&sglist, 0, sizeof(TW_SG_Entry_ISO));
 392         sglist[0].length = TW_SECTOR_SIZE;
 393         sglist[0].address = tw_dev->generic_buffer_phys[request_id];
 394 
 395         /* Mark internal command */
 396         tw_dev->srb[request_id] = NULL;
 397 
 398         /* Now post the command packet */
 399         if (twl_scsiop_execute_scsi(tw_dev, request_id, cdb, 1, sglist)) {
 400                 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x2, "Post failed while reading AEN queue");
 401                 goto out;
 402         }
 403         retval = 0;
 404 out:
 405         return retval;
 406 } /* End twl_aen_read_queue() */
 407 
 408 /* This function will sync firmware time with the host time */
 409 static void twl_aen_sync_time(TW_Device_Extension *tw_dev, int request_id)
 410 {
 411         u32 schedulertime;
 412         TW_Command_Full *full_command_packet;
 413         TW_Command *command_packet;
 414         TW_Param_Apache *param;
 415         time64_t 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         local_time = (ktime_get_real_seconds() - (sys_tz.tz_minuteswest * 60));
 438         div_u64_rem(local_time - (3 * 86400), 604800, &schedulertime);
 439         schedulertime = cpu_to_le32(schedulertime);
 440 
 441         memcpy(param->data, &schedulertime, sizeof(u32));
 442 
 443         /* Mark internal command */
 444         tw_dev->srb[request_id] = NULL;
 445 
 446         /* Now post the command */
 447         twl_post_command_packet(tw_dev, request_id);
 448 } /* End twl_aen_sync_time() */
 449 
 450 /* This function will assign an available request id */
 451 static void twl_get_request_id(TW_Device_Extension *tw_dev, int *request_id)
 452 {
 453         *request_id = tw_dev->free_queue[tw_dev->free_head];
 454         tw_dev->free_head = (tw_dev->free_head + 1) % TW_Q_LENGTH;
 455         tw_dev->state[*request_id] = TW_S_STARTED;
 456 } /* End twl_get_request_id() */
 457 
 458 /* This function will free a request id */
 459 static void twl_free_request_id(TW_Device_Extension *tw_dev, int request_id)
 460 {
 461         tw_dev->free_queue[tw_dev->free_tail] = request_id;
 462         tw_dev->state[request_id] = TW_S_FINISHED;
 463         tw_dev->free_tail = (tw_dev->free_tail + 1) % TW_Q_LENGTH;
 464 } /* End twl_free_request_id() */
 465 
 466 /* This function will complete an aen request from the isr */
 467 static int twl_aen_complete(TW_Device_Extension *tw_dev, int request_id)
 468 {
 469         TW_Command_Full *full_command_packet;
 470         TW_Command *command_packet;
 471         TW_Command_Apache_Header *header;
 472         unsigned short aen;
 473         int retval = 1;
 474 
 475         header = (TW_Command_Apache_Header *)tw_dev->generic_buffer_virt[request_id];
 476         tw_dev->posted_request_count--;
 477         aen = le16_to_cpu(header->status_block.error);
 478         full_command_packet = tw_dev->command_packet_virt[request_id];
 479         command_packet = &full_command_packet->command.oldcommand;
 480 
 481         /* First check for internal completion of set param for time sync */
 482         if (TW_OP_OUT(command_packet->opcode__sgloffset) == TW_OP_SET_PARAM) {
 483                 /* Keep reading the queue in case there are more aen's */
 484                 if (twl_aen_read_queue(tw_dev, request_id))
 485                         goto out2;
 486                 else {
 487                         retval = 0;
 488                         goto out;
 489                 }
 490         }
 491 
 492         switch (aen) {
 493         case TW_AEN_QUEUE_EMPTY:
 494                 /* Quit reading the queue if this is the last one */
 495                 break;
 496         case TW_AEN_SYNC_TIME_WITH_HOST:
 497                 twl_aen_sync_time(tw_dev, request_id);
 498                 retval = 0;
 499                 goto out;
 500         default:
 501                 twl_aen_queue_event(tw_dev, header);
 502 
 503                 /* If there are more aen's, keep reading the queue */
 504                 if (twl_aen_read_queue(tw_dev, request_id))
 505                         goto out2;
 506                 else {
 507                         retval = 0;
 508                         goto out;
 509                 }
 510         }
 511         retval = 0;
 512 out2:
 513         tw_dev->state[request_id] = TW_S_COMPLETED;
 514         twl_free_request_id(tw_dev, request_id);
 515         clear_bit(TW_IN_ATTENTION_LOOP, &tw_dev->flags);
 516 out:
 517         return retval;
 518 } /* End twl_aen_complete() */
 519 
 520 /* This function will poll for a response */
 521 static int twl_poll_response(TW_Device_Extension *tw_dev, int request_id, int seconds)
 522 {
 523         unsigned long before;
 524         dma_addr_t mfa;
 525         u32 regh, regl;
 526         u32 response;
 527         int retval = 1;
 528         int found = 0;
 529 
 530         before = jiffies;
 531 
 532         while (!found) {
 533                 if (sizeof(dma_addr_t) > 4) {
 534                         regh = readl(TWL_HOBQPH_REG_ADDR(tw_dev));
 535                         regl = readl(TWL_HOBQPL_REG_ADDR(tw_dev));
 536                         mfa = ((u64)regh << 32) | regl;
 537                 } else
 538                         mfa = readl(TWL_HOBQPL_REG_ADDR(tw_dev));
 539 
 540                 response = (u32)mfa;
 541 
 542                 if (TW_RESID_OUT(response) == request_id)
 543                         found = 1;
 544 
 545                 if (time_after(jiffies, before + HZ * seconds))
 546                         goto out;
 547 
 548                 msleep(50);
 549         }
 550         retval = 0;
 551 out: 
 552         return retval;
 553 } /* End twl_poll_response() */
 554 
 555 /* This function will drain the aen queue */
 556 static int twl_aen_drain_queue(TW_Device_Extension *tw_dev, int no_check_reset)
 557 {
 558         int request_id = 0;
 559         unsigned char cdb[TW_MAX_CDB_LEN];
 560         TW_SG_Entry_ISO sglist[1];
 561         int finished = 0, count = 0;
 562         TW_Command_Full *full_command_packet;
 563         TW_Command_Apache_Header *header;
 564         unsigned short aen;
 565         int first_reset = 0, queue = 0, retval = 1;
 566 
 567         if (no_check_reset)
 568                 first_reset = 0;
 569         else
 570                 first_reset = 1;
 571 
 572         full_command_packet = tw_dev->command_packet_virt[request_id];
 573         memset(full_command_packet, 0, sizeof(TW_Command_Full));
 574 
 575         /* Initialize cdb */
 576         memset(&cdb, 0, TW_MAX_CDB_LEN);
 577         cdb[0] = REQUEST_SENSE; /* opcode */
 578         cdb[4] = TW_ALLOCATION_LENGTH; /* allocation length */
 579 
 580         /* Initialize sglist */
 581         memset(&sglist, 0, sizeof(TW_SG_Entry_ISO));
 582         sglist[0].length = TW_SECTOR_SIZE;
 583         sglist[0].address = tw_dev->generic_buffer_phys[request_id];
 584 
 585         /* Mark internal command */
 586         tw_dev->srb[request_id] = NULL;
 587 
 588         do {
 589                 /* Send command to the board */
 590                 if (twl_scsiop_execute_scsi(tw_dev, request_id, cdb, 1, sglist)) {
 591                         TW_PRINTK(tw_dev->host, TW_DRIVER, 0x3, "Error posting request sense");
 592                         goto out;
 593                 }
 594 
 595                 /* Now poll for completion */
 596                 if (twl_poll_response(tw_dev, request_id, 30)) {
 597                         TW_PRINTK(tw_dev->host, TW_DRIVER, 0x4, "No valid response while draining AEN queue");
 598                         tw_dev->posted_request_count--;
 599                         goto out;
 600                 }
 601 
 602                 tw_dev->posted_request_count--;
 603                 header = (TW_Command_Apache_Header *)tw_dev->generic_buffer_virt[request_id];
 604                 aen = le16_to_cpu(header->status_block.error);
 605                 queue = 0;
 606                 count++;
 607 
 608                 switch (aen) {
 609                 case TW_AEN_QUEUE_EMPTY:
 610                         if (first_reset != 1)
 611                                 goto out;
 612                         else
 613                                 finished = 1;
 614                         break;
 615                 case TW_AEN_SOFT_RESET:
 616                         if (first_reset == 0)
 617                                 first_reset = 1;
 618                         else
 619                                 queue = 1;
 620                         break;
 621                 case TW_AEN_SYNC_TIME_WITH_HOST:
 622                         break;
 623                 default:
 624                         queue = 1;
 625                 }
 626 
 627                 /* Now queue an event info */
 628                 if (queue)
 629                         twl_aen_queue_event(tw_dev, header);
 630         } while ((finished == 0) && (count < TW_MAX_AEN_DRAIN));
 631 
 632         if (count == TW_MAX_AEN_DRAIN)
 633                 goto out;
 634 
 635         retval = 0;
 636 out:
 637         tw_dev->state[request_id] = TW_S_INITIAL;
 638         return retval;
 639 } /* End twl_aen_drain_queue() */
 640 
 641 /* This function will allocate memory and check if it is correctly aligned */
 642 static int twl_allocate_memory(TW_Device_Extension *tw_dev, int size, int which)
 643 {
 644         int i;
 645         dma_addr_t dma_handle;
 646         unsigned long *cpu_addr;
 647         int retval = 1;
 648 
 649         cpu_addr = dma_alloc_coherent(&tw_dev->tw_pci_dev->dev,
 650                                       size * TW_Q_LENGTH, &dma_handle,
 651                                       GFP_KERNEL);
 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                 dma_free_coherent(&tw_dev->tw_pci_dev->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                 dma_free_coherent(&tw_dev->tw_pci_dev->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                 dma_free_coherent(&tw_dev->tw_pci_dev->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         .shost_attrs            = twl_host_attrs,
1555         .emulated               = 1,
1556         .no_write_same          = 1,
1557 };
1558 
1559 /* This function will probe and initialize a card */
1560 static int twl_probe(struct pci_dev *pdev, const struct pci_device_id *dev_id)
1561 {
1562         struct Scsi_Host *host = NULL;
1563         TW_Device_Extension *tw_dev;
1564         int retval = -ENODEV;
1565         int *ptr_phycount, phycount=0;
1566 
1567         retval = pci_enable_device(pdev);
1568         if (retval) {
1569                 TW_PRINTK(host, TW_DRIVER, 0x17, "Failed to enable pci device");
1570                 goto out_disable_device;
1571         }
1572 
1573         pci_set_master(pdev);
1574         pci_try_set_mwi(pdev);
1575 
1576         retval = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
1577         if (retval)
1578                 retval = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
1579         if (retval) {
1580                 TW_PRINTK(host, TW_DRIVER, 0x18, "Failed to set dma mask");
1581                 retval = -ENODEV;
1582                 goto out_disable_device;
1583         }
1584 
1585         host = scsi_host_alloc(&driver_template, sizeof(TW_Device_Extension));
1586         if (!host) {
1587                 TW_PRINTK(host, TW_DRIVER, 0x19, "Failed to allocate memory for device extension");
1588                 retval = -ENOMEM;
1589                 goto out_disable_device;
1590         }
1591         tw_dev = shost_priv(host);
1592 
1593         /* Save values to device extension */
1594         tw_dev->host = host;
1595         tw_dev->tw_pci_dev = pdev;
1596 
1597         if (twl_initialize_device_extension(tw_dev)) {
1598                 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1a, "Failed to initialize device extension");
1599                 retval = -ENOMEM;
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                 retval = -ENOMEM;
1615                 goto out_release_mem_region;
1616         }
1617 
1618         /* Disable interrupts on the card */
1619         TWL_MASK_INTERRUPTS(tw_dev);
1620 
1621         /* Initialize the card */
1622         if (twl_reset_sequence(tw_dev, 0)) {
1623                 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1d, "Controller reset failed during probe");
1624                 retval = -ENOMEM;
1625                 goto out_iounmap;
1626         }
1627 
1628         /* Set host specific parameters */
1629         host->max_id = TW_MAX_UNITS;
1630         host->max_cmd_len = TW_MAX_CDB_LEN;
1631         host->max_lun = TW_MAX_LUNS;
1632         host->max_channel = 0;
1633 
1634         /* Register the card with the kernel SCSI layer */
1635         retval = scsi_add_host(host, &pdev->dev);
1636         if (retval) {
1637                 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1e, "scsi add host failed");
1638                 goto out_iounmap;
1639         }
1640 
1641         pci_set_drvdata(pdev, host);
1642 
1643         printk(KERN_WARNING "3w-sas: scsi%d: Found an LSI 3ware %s Controller at 0x%llx, IRQ: %d.\n",
1644                host->host_no,
1645                (char *)twl_get_param(tw_dev, 1, TW_VERSION_TABLE,
1646                                      TW_PARAM_MODEL, TW_PARAM_MODEL_LENGTH),
1647                (u64)pci_resource_start(pdev, 1), pdev->irq);
1648 
1649         ptr_phycount = twl_get_param(tw_dev, 2, TW_PARAM_PHY_SUMMARY_TABLE,
1650                                      TW_PARAM_PHYCOUNT, TW_PARAM_PHYCOUNT_LENGTH);
1651         if (ptr_phycount)
1652                 phycount = le32_to_cpu(*(int *)ptr_phycount);
1653 
1654         printk(KERN_WARNING "3w-sas: scsi%d: Firmware %s, BIOS %s, Phys: %d.\n",
1655                host->host_no,
1656                (char *)twl_get_param(tw_dev, 1, TW_VERSION_TABLE,
1657                                      TW_PARAM_FWVER, TW_PARAM_FWVER_LENGTH),
1658                (char *)twl_get_param(tw_dev, 2, TW_VERSION_TABLE,
1659                                      TW_PARAM_BIOSVER, TW_PARAM_BIOSVER_LENGTH),
1660                phycount);
1661 
1662         /* Try to enable MSI */
1663         if (use_msi && !pci_enable_msi(pdev))
1664                 set_bit(TW_USING_MSI, &tw_dev->flags);
1665 
1666         /* Now setup the interrupt handler */
1667         retval = request_irq(pdev->irq, twl_interrupt, IRQF_SHARED, "3w-sas", tw_dev);
1668         if (retval) {
1669                 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1f, "Error requesting IRQ");
1670                 goto out_remove_host;
1671         }
1672 
1673         twl_device_extension_list[twl_device_extension_count] = tw_dev;
1674         twl_device_extension_count++;
1675 
1676         /* Re-enable interrupts on the card */
1677         TWL_UNMASK_INTERRUPTS(tw_dev);
1678         
1679         /* Finally, scan the host */
1680         scsi_scan_host(host);
1681 
1682         /* Add sysfs binary files */
1683         if (sysfs_create_bin_file(&host->shost_dev.kobj, &twl_sysfs_aen_read_attr))
1684                 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x20, "Failed to create sysfs binary file: 3ware_aen_read");
1685         if (sysfs_create_bin_file(&host->shost_dev.kobj, &twl_sysfs_compat_info_attr))
1686                 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x21, "Failed to create sysfs binary file: 3ware_compat_info");
1687 
1688         if (twl_major == -1) {
1689                 if ((twl_major = register_chrdev (0, "twl", &twl_fops)) < 0)
1690                         TW_PRINTK(host, TW_DRIVER, 0x22, "Failed to register character device");
1691         }
1692         tw_dev->online = 1;
1693         return 0;
1694 
1695 out_remove_host:
1696         if (test_bit(TW_USING_MSI, &tw_dev->flags))
1697                 pci_disable_msi(pdev);
1698         scsi_remove_host(host);
1699 out_iounmap:
1700         iounmap(tw_dev->base_addr);
1701 out_release_mem_region:
1702         pci_release_regions(pdev);
1703 out_free_device_extension:
1704         twl_free_device_extension(tw_dev);
1705         scsi_host_put(host);
1706 out_disable_device:
1707         pci_disable_device(pdev);
1708 
1709         return retval;
1710 } /* End twl_probe() */
1711 
1712 /* This function is called to remove a device */
1713 static void twl_remove(struct pci_dev *pdev)
1714 {
1715         struct Scsi_Host *host = pci_get_drvdata(pdev);
1716         TW_Device_Extension *tw_dev;
1717 
1718         if (!host)
1719                 return;
1720 
1721         tw_dev = (TW_Device_Extension *)host->hostdata;
1722 
1723         if (!tw_dev->online)
1724                 return;
1725 
1726         /* Remove sysfs binary files */
1727         sysfs_remove_bin_file(&host->shost_dev.kobj, &twl_sysfs_aen_read_attr);
1728         sysfs_remove_bin_file(&host->shost_dev.kobj, &twl_sysfs_compat_info_attr);
1729 
1730         scsi_remove_host(tw_dev->host);
1731 
1732         /* Unregister character device */
1733         if (twl_major >= 0) {
1734                 unregister_chrdev(twl_major, "twl");
1735                 twl_major = -1;
1736         }
1737 
1738         /* Shutdown the card */
1739         __twl_shutdown(tw_dev);
1740 
1741         /* Disable MSI if enabled */
1742         if (test_bit(TW_USING_MSI, &tw_dev->flags))
1743                 pci_disable_msi(pdev);
1744 
1745         /* Free IO remapping */
1746         iounmap(tw_dev->base_addr);
1747 
1748         /* Free up the mem region */
1749         pci_release_regions(pdev);
1750 
1751         /* Free up device extension resources */
1752         twl_free_device_extension(tw_dev);
1753 
1754         scsi_host_put(tw_dev->host);
1755         pci_disable_device(pdev);
1756         twl_device_extension_count--;
1757 } /* End twl_remove() */
1758 
1759 #ifdef CONFIG_PM
1760 /* This function is called on PCI suspend */
1761 static int twl_suspend(struct pci_dev *pdev, pm_message_t state)
1762 {
1763         struct Scsi_Host *host = pci_get_drvdata(pdev);
1764         TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata;
1765 
1766         printk(KERN_WARNING "3w-sas: Suspending host %d.\n", tw_dev->host->host_no);
1767         /* Disable interrupts */
1768         TWL_MASK_INTERRUPTS(tw_dev);
1769 
1770         free_irq(tw_dev->tw_pci_dev->irq, tw_dev);
1771 
1772         /* Tell the card we are shutting down */
1773         if (twl_initconnection(tw_dev, 1, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL)) {
1774                 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x23, "Connection shutdown failed during suspend");
1775         } else {
1776                 printk(KERN_WARNING "3w-sas: Suspend complete.\n");
1777         }
1778 
1779         /* Clear doorbell interrupt */
1780         TWL_CLEAR_DB_INTERRUPT(tw_dev);
1781 
1782         pci_save_state(pdev);
1783         pci_disable_device(pdev);
1784         pci_set_power_state(pdev, pci_choose_state(pdev, state));
1785 
1786         return 0;
1787 } /* End twl_suspend() */
1788 
1789 /* This function is called on PCI resume */
1790 static int twl_resume(struct pci_dev *pdev)
1791 {
1792         int retval = 0;
1793         struct Scsi_Host *host = pci_get_drvdata(pdev);
1794         TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata;
1795 
1796         printk(KERN_WARNING "3w-sas: Resuming host %d.\n", tw_dev->host->host_no);
1797         pci_set_power_state(pdev, PCI_D0);
1798         pci_enable_wake(pdev, PCI_D0, 0);
1799         pci_restore_state(pdev);
1800 
1801         retval = pci_enable_device(pdev);
1802         if (retval) {
1803                 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x24, "Enable device failed during resume");
1804                 return retval;
1805         }
1806 
1807         pci_set_master(pdev);
1808         pci_try_set_mwi(pdev);
1809 
1810         retval = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
1811         if (retval)
1812                 retval = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
1813         if (retval) {
1814                 TW_PRINTK(host, TW_DRIVER, 0x25, "Failed to set dma mask during resume");
1815                 retval = -ENODEV;
1816                 goto out_disable_device;
1817         }
1818 
1819         /* Initialize the card */
1820         if (twl_reset_sequence(tw_dev, 0)) {
1821                 retval = -ENODEV;
1822                 goto out_disable_device;
1823         }
1824 
1825         /* Now setup the interrupt handler */
1826         retval = request_irq(pdev->irq, twl_interrupt, IRQF_SHARED, "3w-sas", tw_dev);
1827         if (retval) {
1828                 TW_PRINTK(tw_dev->host, TW_DRIVER, 0x26, "Error requesting IRQ during resume");
1829                 retval = -ENODEV;
1830                 goto out_disable_device;
1831         }
1832 
1833         /* Now enable MSI if enabled */
1834         if (test_bit(TW_USING_MSI, &tw_dev->flags))
1835                 pci_enable_msi(pdev);
1836 
1837         /* Re-enable interrupts on the card */
1838         TWL_UNMASK_INTERRUPTS(tw_dev);
1839 
1840         printk(KERN_WARNING "3w-sas: Resume complete.\n");
1841         return 0;
1842 
1843 out_disable_device:
1844         scsi_remove_host(host);
1845         pci_disable_device(pdev);
1846 
1847         return retval;
1848 } /* End twl_resume() */
1849 #endif
1850 
1851 /* PCI Devices supported by this driver */
1852 static struct pci_device_id twl_pci_tbl[] = {
1853         { PCI_VDEVICE(3WARE, PCI_DEVICE_ID_3WARE_9750) },
1854         { }
1855 };
1856 MODULE_DEVICE_TABLE(pci, twl_pci_tbl);
1857 
1858 /* pci_driver initializer */
1859 static struct pci_driver twl_driver = {
1860         .name           = "3w-sas",
1861         .id_table       = twl_pci_tbl,
1862         .probe          = twl_probe,
1863         .remove         = twl_remove,
1864 #ifdef CONFIG_PM
1865         .suspend        = twl_suspend,
1866         .resume         = twl_resume,
1867 #endif
1868         .shutdown       = twl_shutdown
1869 };
1870 
1871 /* This function is called on driver initialization */
1872 static int __init twl_init(void)
1873 {
1874         printk(KERN_INFO "LSI 3ware SAS/SATA-RAID Controller device driver for Linux v%s.\n", TW_DRIVER_VERSION);
1875 
1876         return pci_register_driver(&twl_driver);
1877 } /* End twl_init() */
1878 
1879 /* This function is called on driver exit */
1880 static void __exit twl_exit(void)
1881 {
1882         pci_unregister_driver(&twl_driver);
1883 } /* End twl_exit() */
1884 
1885 module_init(twl_init);
1886 module_exit(twl_exit);
1887 

/* [<][>][^][v][top][bottom][index][help] */