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