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 <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"
  76static DEFINE_MUTEX(twl_chrdev_mutex);
  77static TW_Device_Extension *twl_device_extension_list[TW_MAX_SLOT];
  78static unsigned int twl_device_extension_count;
  79static int twl_major = -1;
  80extern struct timezone sys_tz;
  81
  82/* Module parameters */
  83MODULE_AUTHOR ("LSI");
  84MODULE_DESCRIPTION ("LSI 3ware SAS/SATA-RAID Linux Driver");
  85MODULE_LICENSE("GPL");
  86MODULE_VERSION(TW_DRIVER_VERSION);
  87
  88static int use_msi;
  89module_param(use_msi, int, S_IRUGO);
  90MODULE_PARM_DESC(use_msi, "Use Message Signaled Interrupts. Default: 0");
  91
  92/* Function prototypes */
  93static int twl_reset_device_extension(TW_Device_Extension *tw_dev, int ioctl_reset);
  94
  95/* Functions */
  96
  97/* This function returns AENs through sysfs */
  98static 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 */
 119static 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 */
 129static 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 */
 150static 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 */
 160static 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 */
 192static 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 */
 201static 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 */
 207static 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];
 216out:
 217        return retval;
 218} /* End twl_aen_severity_lookup() */
 219
 220/* This function will queue an event */
 221static void twl_aen_queue_event(TW_Device_Extension *tw_dev, TW_Command_Apache_Header *header)
 222{
 223        u32 local_time;
 224        struct timeval time;
 225        TW_Event *event;
 226        unsigned short aen;
 227        char host[16];
 228        char *error_str;
 229
 230        tw_dev->aen_count++;
 231
 232        /* Fill out event info */
 233        event = tw_dev->event_queue[tw_dev->error_index];
 234
 235        host[0] = '\0';
 236        if (tw_dev->host)
 237                sprintf(host, " scsi%d:", tw_dev->host->host_no);
 238
 239        aen = le16_to_cpu(header->status_block.error);
 240        memset(event, 0, sizeof(TW_Event));
 241
 242        event->severity = TW_SEV_OUT(header->status_block.severity__reserved);
 243        do_gettimeofday(&time);
 244        local_time = (u32)(time.tv_sec - (sys_tz.tz_minuteswest * 60));
 245        event->time_stamp_sec = local_time;
 246        event->aen_code = aen;
 247        event->retrieved = TW_AEN_NOT_RETRIEVED;
 248        event->sequence_id = tw_dev->error_sequence_id;
 249        tw_dev->error_sequence_id++;
 250
 251        /* Check for embedded error string */
 252        error_str = &(header->err_specific_desc[strlen(header->err_specific_desc)+1]);
 253
 254        header->err_specific_desc[sizeof(header->err_specific_desc) - 1] = '\0';
 255        event->parameter_len = strlen(header->err_specific_desc);
 256        memcpy(event->parameter_data, header->err_specific_desc, event->parameter_len + 1 + strlen(error_str));
 257        if (event->severity != TW_AEN_SEVERITY_DEBUG)
 258                printk(KERN_WARNING "3w-sas:%s AEN: %s (0x%02X:0x%04X): %s:%s.\n",
 259                       host,
 260                       twl_aen_severity_lookup(TW_SEV_OUT(header->status_block.severity__reserved)),
 261                       TW_MESSAGE_SOURCE_CONTROLLER_EVENT, aen, error_str,
 262                       header->err_specific_desc);
 263        else
 264                tw_dev->aen_count--;
 265
 266        tw_dev->error_index = (tw_dev->error_index + 1 ) % TW_Q_LENGTH;
 267} /* End twl_aen_queue_event() */
 268
 269/* This function will attempt to post a command packet to the board */
 270static int twl_post_command_packet(TW_Device_Extension *tw_dev, int request_id)
 271{
 272        dma_addr_t command_que_value;
 273
 274        command_que_value = tw_dev->command_packet_phys[request_id];
 275        command_que_value += TW_COMMAND_OFFSET;
 276
 277        /* First write upper 4 bytes */
 278        writel((u32)((u64)command_que_value >> 32), TWL_HIBQPH_REG_ADDR(tw_dev));
 279        /* Then the lower 4 bytes */
 280        writel((u32)(command_que_value | TWL_PULL_MODE), TWL_HIBQPL_REG_ADDR(tw_dev));
 281
 282        tw_dev->state[request_id] = TW_S_POSTED;
 283        tw_dev->posted_request_count++;
 284        if (tw_dev->posted_request_count > tw_dev->max_posted_request_count)
 285                tw_dev->max_posted_request_count = tw_dev->posted_request_count;
 286
 287        return 0;
 288} /* End twl_post_command_packet() */
 289
 290/* This function hands scsi cdb's to the firmware */
 291static int twl_scsiop_execute_scsi(TW_Device_Extension *tw_dev, int request_id, char *cdb, int use_sg, TW_SG_Entry_ISO *sglistarg)
 292{
 293        TW_Command_Full *full_command_packet;
 294        TW_Command_Apache *command_packet;
 295        int i, sg_count;
 296        struct scsi_cmnd *srb = NULL;
 297        struct scatterlist *sglist = NULL, *sg;
 298        int retval = 1;
 299
 300        if (tw_dev->srb[request_id]) {
 301                srb = tw_dev->srb[request_id];
 302                if (scsi_sglist(srb))
 303                        sglist = scsi_sglist(srb);
 304        }
 305
 306        /* Initialize command packet */
 307        full_command_packet = tw_dev->command_packet_virt[request_id];
 308        full_command_packet->header.header_desc.size_header = 128;
 309        full_command_packet->header.status_block.error = 0;
 310        full_command_packet->header.status_block.severity__reserved = 0;
 311
 312        command_packet = &full_command_packet->command.newcommand;
 313        command_packet->status = 0;
 314        command_packet->opcode__reserved = TW_OPRES_IN(0, TW_OP_EXECUTE_SCSI);
 315
 316        /* We forced 16 byte cdb use earlier */
 317        if (!cdb)
 318                memcpy(command_packet->cdb, srb->cmnd, TW_MAX_CDB_LEN);
 319        else
 320                memcpy(command_packet->cdb, cdb, TW_MAX_CDB_LEN);
 321
 322        if (srb) {
 323                command_packet->unit = srb->device->id;
 324                command_packet->request_id__lunl =
 325                        cpu_to_le16(TW_REQ_LUN_IN(srb->device->lun, request_id));
 326        } else {
 327                command_packet->request_id__lunl =
 328                        cpu_to_le16(TW_REQ_LUN_IN(0, request_id));
 329                command_packet->unit = 0;
 330        }
 331
 332        command_packet->sgl_offset = 16;
 333
 334        if (!sglistarg) {
 335                /* Map sglist from scsi layer to cmd packet */
 336                if (scsi_sg_count(srb)) {
 337                        sg_count = scsi_dma_map(srb);
 338                        if (sg_count <= 0)
 339                                goto out;
 340
 341                        scsi_for_each_sg(srb, sg, sg_count, i) {
 342                                command_packet->sg_list[i].address = TW_CPU_TO_SGL(sg_dma_address(sg));
 343                                command_packet->sg_list[i].length = TW_CPU_TO_SGL(sg_dma_len(sg));
 344                        }
 345                        command_packet->sgl_entries__lunh = cpu_to_le16(TW_REQ_LUN_IN((srb->device->lun >> 4), scsi_sg_count(tw_dev->srb[request_id])));
 346                }
 347        } else {
 348                /* Internal cdb post */
 349                for (i = 0; i < use_sg; i++) {
 350                        command_packet->sg_list[i].address = TW_CPU_TO_SGL(sglistarg[i].address);
 351                        command_packet->sg_list[i].length = TW_CPU_TO_SGL(sglistarg[i].length);
 352                }
 353                command_packet->sgl_entries__lunh = cpu_to_le16(TW_REQ_LUN_IN(0, use_sg));
 354        }
 355
 356        /* Update some stats */
 357        if (srb) {
 358                tw_dev->sector_count = scsi_bufflen(srb) / 512;
 359                if (tw_dev->sector_count > tw_dev->max_sector_count)
 360                        tw_dev->max_sector_count = tw_dev->sector_count;
 361                tw_dev->sgl_entries = scsi_sg_count(srb);
 362                if (tw_dev->sgl_entries > tw_dev->max_sgl_entries)
 363                        tw_dev->max_sgl_entries = tw_dev->sgl_entries;
 364        }
 365
 366        /* Now post the command to the board */
 367        retval = twl_post_command_packet(tw_dev, request_id);
 368
 369out:
 370        return retval;
 371} /* End twl_scsiop_execute_scsi() */
 372
 373/* This function will read the aen queue from the isr */
 374static int twl_aen_read_queue(TW_Device_Extension *tw_dev, int request_id)
 375{
 376        char cdb[TW_MAX_CDB_LEN];
 377        TW_SG_Entry_ISO sglist[1];
 378        TW_Command_Full *full_command_packet;
 379        int retval = 1;
 380
 381        full_command_packet = tw_dev->command_packet_virt[request_id];
 382        memset(full_command_packet, 0, sizeof(TW_Command_Full));
 383
 384        /* Initialize cdb */
 385        memset(&cdb, 0, TW_MAX_CDB_LEN);
 386        cdb[0] = REQUEST_SENSE; /* opcode */
 387        cdb[4] = TW_ALLOCATION_LENGTH; /* allocation length */
 388
 389        /* Initialize sglist */
 390        memset(&sglist, 0, sizeof(TW_SG_Entry_ISO));
 391        sglist[0].length = TW_SECTOR_SIZE;
 392        sglist[0].address = tw_dev->generic_buffer_phys[request_id];
 393
 394        /* Mark internal command */
 395        tw_dev->srb[request_id] = NULL;
 396
 397        /* Now post the command packet */
 398        if (twl_scsiop_execute_scsi(tw_dev, request_id, cdb, 1, sglist)) {
 399                TW_PRINTK(tw_dev->host, TW_DRIVER, 0x2, "Post failed while reading AEN queue");
 400                goto out;
 401        }
 402        retval = 0;
 403out:
 404        return retval;
 405} /* End twl_aen_read_queue() */
 406
 407/* This function will sync firmware time with the host time */
 408static void twl_aen_sync_time(TW_Device_Extension *tw_dev, int request_id)
 409{
 410        u32 schedulertime;
 411        struct timeval utc;
 412        TW_Command_Full *full_command_packet;
 413        TW_Command *command_packet;
 414        TW_Param_Apache *param;
 415        u32 local_time;
 416
 417        /* Fill out the command packet */
 418        full_command_packet = tw_dev->command_packet_virt[request_id];
 419        memset(full_command_packet, 0, sizeof(TW_Command_Full));
 420        command_packet = &full_command_packet->command.oldcommand;
 421        command_packet->opcode__sgloffset = TW_OPSGL_IN(2, TW_OP_SET_PARAM);
 422        command_packet->request_id = request_id;
 423        command_packet->byte8_offset.param.sgl[0].address = TW_CPU_TO_SGL(tw_dev->generic_buffer_phys[request_id]);
 424        command_packet->byte8_offset.param.sgl[0].length = TW_CPU_TO_SGL(TW_SECTOR_SIZE);
 425        command_packet->size = TW_COMMAND_SIZE;
 426        command_packet->byte6_offset.parameter_count = cpu_to_le16(1);
 427
 428        /* Setup the param */
 429        param = (TW_Param_Apache *)tw_dev->generic_buffer_virt[request_id];
 430        memset(param, 0, TW_SECTOR_SIZE);
 431        param->table_id = cpu_to_le16(TW_TIMEKEEP_TABLE | 0x8000); /* Controller time keep table */
 432        param->parameter_id = cpu_to_le16(0x3); /* SchedulerTime */
 433        param->parameter_size_bytes = cpu_to_le16(4);
 434
 435        /* Convert system time in UTC to local time seconds since last 
 436           Sunday 12:00AM */
 437        do_gettimeofday(&utc);
 438        local_time = (u32)(utc.tv_sec - (sys_tz.tz_minuteswest * 60));
 439        schedulertime = local_time - (3 * 86400);
 440        schedulertime = cpu_to_le32(schedulertime % 604800);
 441
 442        memcpy(param->data, &schedulertime, sizeof(u32));
 443
 444        /* Mark internal command */
 445        tw_dev->srb[request_id] = NULL;
 446
 447        /* Now post the command */
 448        twl_post_command_packet(tw_dev, request_id);
 449} /* End twl_aen_sync_time() */
 450
 451/* This function will assign an available request id */
 452static void twl_get_request_id(TW_Device_Extension *tw_dev, int *request_id)
 453{
 454        *request_id = tw_dev->free_queue[tw_dev->free_head];
 455        tw_dev->free_head = (tw_dev->free_head + 1) % TW_Q_LENGTH;
 456        tw_dev->state[*request_id] = TW_S_STARTED;
 457} /* End twl_get_request_id() */
 458
 459/* This function will free a request id */
 460static void twl_free_request_id(TW_Device_Extension *tw_dev, int request_id)
 461{
 462        tw_dev->free_queue[tw_dev->free_tail] = request_id;
 463        tw_dev->state[request_id] = TW_S_FINISHED;
 464        tw_dev->free_tail = (tw_dev->free_tail + 1) % TW_Q_LENGTH;
 465} /* End twl_free_request_id() */
 466
 467/* This function will complete an aen request from the isr */
 468static int twl_aen_complete(TW_Device_Extension *tw_dev, int request_id)
 469{
 470        TW_Command_Full *full_command_packet;
 471        TW_Command *command_packet;
 472        TW_Command_Apache_Header *header;
 473        unsigned short aen;
 474        int retval = 1;
 475
 476        header = (TW_Command_Apache_Header *)tw_dev->generic_buffer_virt[request_id];
 477        tw_dev->posted_request_count--;
 478        aen = le16_to_cpu(header->status_block.error);
 479        full_command_packet = tw_dev->command_packet_virt[request_id];
 480        command_packet = &full_command_packet->command.oldcommand;
 481
 482        /* First check for internal completion of set param for time sync */
 483        if (TW_OP_OUT(command_packet->opcode__sgloffset) == TW_OP_SET_PARAM) {
 484                /* Keep reading the queue in case there are more aen's */
 485                if (twl_aen_read_queue(tw_dev, request_id))
 486                        goto out2;
 487                else {
 488                        retval = 0;
 489                        goto out;
 490                }
 491        }
 492
 493        switch (aen) {
 494        case TW_AEN_QUEUE_EMPTY:
 495                /* Quit reading the queue if this is the last one */
 496                break;
 497        case TW_AEN_SYNC_TIME_WITH_HOST:
 498                twl_aen_sync_time(tw_dev, request_id);
 499                retval = 0;
 500                goto out;
 501        default:
 502                twl_aen_queue_event(tw_dev, header);
 503
 504                /* If there are more aen's, keep reading the queue */
 505                if (twl_aen_read_queue(tw_dev, request_id))
 506                        goto out2;
 507                else {
 508                        retval = 0;
 509                        goto out;
 510                }
 511        }
 512        retval = 0;
 513out2:
 514        tw_dev->state[request_id] = TW_S_COMPLETED;
 515        twl_free_request_id(tw_dev, request_id);
 516        clear_bit(TW_IN_ATTENTION_LOOP, &tw_dev->flags);
 517out:
 518        return retval;
 519} /* End twl_aen_complete() */
 520
 521/* This function will poll for a response */
 522static int twl_poll_response(TW_Device_Extension *tw_dev, int request_id, int seconds)
 523{
 524        unsigned long before;
 525        dma_addr_t mfa;
 526        u32 regh, regl;
 527        u32 response;
 528        int retval = 1;
 529        int found = 0;
 530
 531        before = jiffies;
 532
 533        while (!found) {
 534                if (sizeof(dma_addr_t) > 4) {
 535                        regh = readl(TWL_HOBQPH_REG_ADDR(tw_dev));
 536                        regl = readl(TWL_HOBQPL_REG_ADDR(tw_dev));
 537                        mfa = ((u64)regh << 32) | regl;
 538                } else
 539                        mfa = readl(TWL_HOBQPL_REG_ADDR(tw_dev));
 540
 541                response = (u32)mfa;
 542
 543                if (TW_RESID_OUT(response) == request_id)
 544                        found = 1;
 545
 546                if (time_after(jiffies, before + HZ * seconds))
 547                        goto out;
 548
 549                msleep(50);
 550        }
 551        retval = 0;
 552out: 
 553        return retval;
 554} /* End twl_poll_response() */
 555
 556/* This function will drain the aen queue */
 557static int twl_aen_drain_queue(TW_Device_Extension *tw_dev, int no_check_reset)
 558{
 559        int request_id = 0;
 560        char cdb[TW_MAX_CDB_LEN];
 561        TW_SG_Entry_ISO sglist[1];
 562        int finished = 0, count = 0;
 563        TW_Command_Full *full_command_packet;
 564        TW_Command_Apache_Header *header;
 565        unsigned short aen;
 566        int first_reset = 0, queue = 0, retval = 1;
 567
 568        if (no_check_reset)
 569                first_reset = 0;
 570        else
 571                first_reset = 1;
 572
 573        full_command_packet = tw_dev->command_packet_virt[request_id];
 574        memset(full_command_packet, 0, sizeof(TW_Command_Full));
 575
 576        /* Initialize cdb */
 577        memset(&cdb, 0, TW_MAX_CDB_LEN);
 578        cdb[0] = REQUEST_SENSE; /* opcode */
 579        cdb[4] = TW_ALLOCATION_LENGTH; /* allocation length */
 580
 581        /* Initialize sglist */
 582        memset(&sglist, 0, sizeof(TW_SG_Entry_ISO));
 583        sglist[0].length = TW_SECTOR_SIZE;
 584        sglist[0].address = tw_dev->generic_buffer_phys[request_id];
 585
 586        /* Mark internal command */
 587        tw_dev->srb[request_id] = NULL;
 588
 589        do {
 590                /* Send command to the board */
 591                if (twl_scsiop_execute_scsi(tw_dev, request_id, cdb, 1, sglist)) {
 592                        TW_PRINTK(tw_dev->host, TW_DRIVER, 0x3, "Error posting request sense");
 593                        goto out;
 594                }
 595
 596                /* Now poll for completion */
 597                if (twl_poll_response(tw_dev, request_id, 30)) {
 598                        TW_PRINTK(tw_dev->host, TW_DRIVER, 0x4, "No valid response while draining AEN queue");
 599                        tw_dev->posted_request_count--;
 600                        goto out;
 601                }
 602
 603                tw_dev->posted_request_count--;
 604                header = (TW_Command_Apache_Header *)tw_dev->generic_buffer_virt[request_id];
 605                aen = le16_to_cpu(header->status_block.error);
 606                queue = 0;
 607                count++;
 608
 609                switch (aen) {
 610                case TW_AEN_QUEUE_EMPTY:
 611                        if (first_reset != 1)
 612                                goto out;
 613                        else
 614                                finished = 1;
 615                        break;
 616                case TW_AEN_SOFT_RESET:
 617                        if (first_reset == 0)
 618                                first_reset = 1;
 619                        else
 620                                queue = 1;
 621                        break;
 622                case TW_AEN_SYNC_TIME_WITH_HOST:
 623                        break;
 624                default:
 625                        queue = 1;
 626                }
 627
 628                /* Now queue an event info */
 629                if (queue)
 630                        twl_aen_queue_event(tw_dev, header);
 631        } while ((finished == 0) && (count < TW_MAX_AEN_DRAIN));
 632
 633        if (count == TW_MAX_AEN_DRAIN)
 634                goto out;
 635
 636        retval = 0;
 637out:
 638        tw_dev->state[request_id] = TW_S_INITIAL;
 639        return retval;
 640} /* End twl_aen_drain_queue() */
 641
 642/* This function will allocate memory and check if it is correctly aligned */
 643static int twl_allocate_memory(TW_Device_Extension *tw_dev, int size, int which)
 644{
 645        int i;
 646        dma_addr_t dma_handle;
 647        unsigned long *cpu_addr;
 648        int retval = 1;
 649
 650        cpu_addr = pci_zalloc_consistent(tw_dev->tw_pci_dev, size * TW_Q_LENGTH,
 651                                         &dma_handle);
 652        if (!cpu_addr) {
 653                TW_PRINTK(tw_dev->host, TW_DRIVER, 0x5, "Memory allocation failed");
 654                goto out;
 655        }
 656
 657        for (i = 0; i < TW_Q_LENGTH; i++) {
 658                switch(which) {
 659                case 0:
 660                        tw_dev->command_packet_phys[i] = dma_handle+(i*size);
 661                        tw_dev->command_packet_virt[i] = (TW_Command_Full *)((unsigned char *)cpu_addr + (i*size));
 662                        break;
 663                case 1:
 664                        tw_dev->generic_buffer_phys[i] = dma_handle+(i*size);
 665                        tw_dev->generic_buffer_virt[i] = (unsigned long *)((unsigned char *)cpu_addr + (i*size));
 666                        break;
 667                case 2:
 668                        tw_dev->sense_buffer_phys[i] = dma_handle+(i*size);
 669                        tw_dev->sense_buffer_virt[i] = (TW_Command_Apache_Header *)((unsigned char *)cpu_addr + (i*size));
 670                        break;
 671                }
 672        }
 673        retval = 0;
 674out:
 675        return retval;
 676} /* End twl_allocate_memory() */
 677
 678/* This function will load the request id and various sgls for ioctls */
 679static 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 */
 716static 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;
 821out3:
 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);
 824out2:
 825        mutex_unlock(&tw_dev->ioctl_lock);
 826out:
 827        mutex_unlock(&twl_chrdev_mutex);
 828        return retval;
 829} /* End twl_chrdev_ioctl() */
 830
 831/* This function handles open for the character device */
 832static 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;
 846out:
 847        return retval;
 848} /* End twl_chrdev_open() */
 849
 850/* File operations struct for character device */
 851static 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 */
 860static 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        }
 897out:
 898        return retval;
 899} /* End twl_fill_sense() */
 900
 901/* This function will free up device extension resources */
 902static void twl_free_device_extension(TW_Device_Extension *tw_dev)
 903{
 904        if (tw_dev->command_packet_virt[0])
 905                pci_free_consistent(tw_dev->tw_pci_dev,
 906                                    sizeof(TW_Command_Full)*TW_Q_LENGTH,
 907                                    tw_dev->command_packet_virt[0],
 908                                    tw_dev->command_packet_phys[0]);
 909
 910        if (tw_dev->generic_buffer_virt[0])
 911                pci_free_consistent(tw_dev->tw_pci_dev,
 912                                    TW_SECTOR_SIZE*TW_Q_LENGTH,
 913                                    tw_dev->generic_buffer_virt[0],
 914                                    tw_dev->generic_buffer_phys[0]);
 915
 916        if (tw_dev->sense_buffer_virt[0])
 917                pci_free_consistent(tw_dev->tw_pci_dev,
 918                                    sizeof(TW_Command_Apache_Header)*
 919                                    TW_Q_LENGTH,
 920                                    tw_dev->sense_buffer_virt[0],
 921                                    tw_dev->sense_buffer_phys[0]);
 922
 923        kfree(tw_dev->event_queue[0]);
 924} /* End twl_free_device_extension() */
 925
 926/* This function will get parameter table entries from the firmware */
 927static 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 */
 970static 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 */
1034static 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;
1078out:
1079        return retval;
1080} /* End twl_initialize_device_extension() */
1081
1082/* This function will handle attention interrupts */
1083static 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;
1110out:
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 */
1121static 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
1233twl_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 */
1239static 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;
1255out:
1256        return retval;
1257} /* End twl_poll_register() */
1258
1259/* This function will reset a controller */
1260static 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        }
1346out:
1347        return retval;
1348} /* End twl_reset_sequence() */
1349
1350/* This function will reset a device extension */
1351static 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;
1401out:
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 */
1408static 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 */
1431static 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;
1454out:
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 */
1460static 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        }
1488out:
1489        return retval;
1490} /* End twl_scsi_queue() */
1491
1492static DEF_SCSI_QCMD(twl_scsi_queue)
1493
1494/* This function tells the controller to shut down */
1495static 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 */
1517static 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 */
1532static 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 */
1541static struct scsi_host_template driver_template = {
1542        .module                 = THIS_MODULE,
1543        .name                   = "3w-sas",
1544        .queuecommand           = twl_scsi_queue,
1545        .eh_host_reset_handler  = twl_scsi_eh_reset,
1546        .bios_param             = twl_scsi_biosparam,
1547        .change_queue_depth     = scsi_change_queue_depth,
1548        .can_queue              = TW_Q_LENGTH-2,
1549        .slave_configure        = twl_slave_configure,
1550        .this_id                = -1,
1551        .sg_tablesize           = TW_LIBERATOR_MAX_SGL_LENGTH,
1552        .max_sectors            = TW_MAX_SECTORS,
1553        .cmd_per_lun            = TW_MAX_CMDS_PER_LUN,
1554        .use_clustering         = ENABLE_CLUSTERING,
1555        .shost_attrs            = twl_host_attrs,
1556        .emulated               = 1,
1557        .no_write_same          = 1,
1558};
1559
1560/* This function will probe and initialize a card */
1561static int twl_probe(struct pci_dev *pdev, const struct pci_device_id *dev_id)
1562{
1563        struct Scsi_Host *host = NULL;
1564        TW_Device_Extension *tw_dev;
1565        int retval = -ENODEV;
1566        int *ptr_phycount, phycount=0;
1567
1568        retval = pci_enable_device(pdev);
1569        if (retval) {
1570                TW_PRINTK(host, TW_DRIVER, 0x17, "Failed to enable pci device");
1571                goto out_disable_device;
1572        }
1573
1574        pci_set_master(pdev);
1575        pci_try_set_mwi(pdev);
1576
1577        if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64))
1578            || pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)))
1579                if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32))
1580                    || pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) {
1581                        TW_PRINTK(host, TW_DRIVER, 0x18, "Failed to set dma mask");
1582                        retval = -ENODEV;
1583                        goto out_disable_device;
1584                }
1585
1586        host = scsi_host_alloc(&driver_template, sizeof(TW_Device_Extension));
1587        if (!host) {
1588                TW_PRINTK(host, TW_DRIVER, 0x19, "Failed to allocate memory for device extension");
1589                retval = -ENOMEM;
1590                goto out_disable_device;
1591        }
1592        tw_dev = shost_priv(host);
1593
1594        /* Save values to device extension */
1595        tw_dev->host = host;
1596        tw_dev->tw_pci_dev = pdev;
1597
1598        if (twl_initialize_device_extension(tw_dev)) {
1599                TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1a, "Failed to initialize device extension");
1600                goto out_free_device_extension;
1601        }
1602
1603        /* Request IO regions */
1604        retval = pci_request_regions(pdev, "3w-sas");
1605        if (retval) {
1606                TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1b, "Failed to get mem region");
1607                goto out_free_device_extension;
1608        }
1609
1610        /* Save base address, use region 1 */
1611        tw_dev->base_addr = pci_iomap(pdev, 1, 0);
1612        if (!tw_dev->base_addr) {
1613                TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1c, "Failed to ioremap");
1614                goto out_release_mem_region;
1615        }
1616
1617        /* Disable interrupts on the card */
1618        TWL_MASK_INTERRUPTS(tw_dev);
1619
1620        /* Initialize the card */
1621        if (twl_reset_sequence(tw_dev, 0)) {
1622                TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1d, "Controller reset failed during probe");
1623                goto out_iounmap;
1624        }
1625
1626        /* Set host specific parameters */
1627        host->max_id = TW_MAX_UNITS;
1628        host->max_cmd_len = TW_MAX_CDB_LEN;
1629        host->max_lun = TW_MAX_LUNS;
1630        host->max_channel = 0;
1631
1632        /* Register the card with the kernel SCSI layer */
1633        retval = scsi_add_host(host, &pdev->dev);
1634        if (retval) {
1635                TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1e, "scsi add host failed");
1636                goto out_iounmap;
1637        }
1638
1639        pci_set_drvdata(pdev, host);
1640
1641        printk(KERN_WARNING "3w-sas: scsi%d: Found an LSI 3ware %s Controller at 0x%llx, IRQ: %d.\n",
1642               host->host_no,
1643               (char *)twl_get_param(tw_dev, 1, TW_VERSION_TABLE,
1644                                     TW_PARAM_MODEL, TW_PARAM_MODEL_LENGTH),
1645               (u64)pci_resource_start(pdev, 1), pdev->irq);
1646
1647        ptr_phycount = twl_get_param(tw_dev, 2, TW_PARAM_PHY_SUMMARY_TABLE,
1648                                     TW_PARAM_PHYCOUNT, TW_PARAM_PHYCOUNT_LENGTH);
1649        if (ptr_phycount)
1650                phycount = le32_to_cpu(*(int *)ptr_phycount);
1651
1652        printk(KERN_WARNING "3w-sas: scsi%d: Firmware %s, BIOS %s, Phys: %d.\n",
1653               host->host_no,
1654               (char *)twl_get_param(tw_dev, 1, TW_VERSION_TABLE,
1655                                     TW_PARAM_FWVER, TW_PARAM_FWVER_LENGTH),
1656               (char *)twl_get_param(tw_dev, 2, TW_VERSION_TABLE,
1657                                     TW_PARAM_BIOSVER, TW_PARAM_BIOSVER_LENGTH),
1658               phycount);
1659
1660        /* Try to enable MSI */
1661        if (use_msi && !pci_enable_msi(pdev))
1662                set_bit(TW_USING_MSI, &tw_dev->flags);
1663
1664        /* Now setup the interrupt handler */
1665        retval = request_irq(pdev->irq, twl_interrupt, IRQF_SHARED, "3w-sas", tw_dev);
1666        if (retval) {
1667                TW_PRINTK(tw_dev->host, TW_DRIVER, 0x1f, "Error requesting IRQ");
1668                goto out_remove_host;
1669        }
1670
1671        twl_device_extension_list[twl_device_extension_count] = tw_dev;
1672        twl_device_extension_count++;
1673
1674        /* Re-enable interrupts on the card */
1675        TWL_UNMASK_INTERRUPTS(tw_dev);
1676        
1677        /* Finally, scan the host */
1678        scsi_scan_host(host);
1679
1680        /* Add sysfs binary files */
1681        if (sysfs_create_bin_file(&host->shost_dev.kobj, &twl_sysfs_aen_read_attr))
1682                TW_PRINTK(tw_dev->host, TW_DRIVER, 0x20, "Failed to create sysfs binary file: 3ware_aen_read");
1683        if (sysfs_create_bin_file(&host->shost_dev.kobj, &twl_sysfs_compat_info_attr))
1684                TW_PRINTK(tw_dev->host, TW_DRIVER, 0x21, "Failed to create sysfs binary file: 3ware_compat_info");
1685
1686        if (twl_major == -1) {
1687                if ((twl_major = register_chrdev (0, "twl", &twl_fops)) < 0)
1688                        TW_PRINTK(host, TW_DRIVER, 0x22, "Failed to register character device");
1689        }
1690        tw_dev->online = 1;
1691        return 0;
1692
1693out_remove_host:
1694        if (test_bit(TW_USING_MSI, &tw_dev->flags))
1695                pci_disable_msi(pdev);
1696        scsi_remove_host(host);
1697out_iounmap:
1698        iounmap(tw_dev->base_addr);
1699out_release_mem_region:
1700        pci_release_regions(pdev);
1701out_free_device_extension:
1702        twl_free_device_extension(tw_dev);
1703        scsi_host_put(host);
1704out_disable_device:
1705        pci_disable_device(pdev);
1706
1707        return retval;
1708} /* End twl_probe() */
1709
1710/* This function is called to remove a device */
1711static void twl_remove(struct pci_dev *pdev)
1712{
1713        struct Scsi_Host *host = pci_get_drvdata(pdev);
1714        TW_Device_Extension *tw_dev;
1715
1716        if (!host)
1717                return;
1718
1719        tw_dev = (TW_Device_Extension *)host->hostdata;
1720
1721        if (!tw_dev->online)
1722                return;
1723
1724        /* Remove sysfs binary files */
1725        sysfs_remove_bin_file(&host->shost_dev.kobj, &twl_sysfs_aen_read_attr);
1726        sysfs_remove_bin_file(&host->shost_dev.kobj, &twl_sysfs_compat_info_attr);
1727
1728        scsi_remove_host(tw_dev->host);
1729
1730        /* Unregister character device */
1731        if (twl_major >= 0) {
1732                unregister_chrdev(twl_major, "twl");
1733                twl_major = -1;
1734        }
1735
1736        /* Shutdown the card */
1737        __twl_shutdown(tw_dev);
1738
1739        /* Disable MSI if enabled */
1740        if (test_bit(TW_USING_MSI, &tw_dev->flags))
1741                pci_disable_msi(pdev);
1742
1743        /* Free IO remapping */
1744        iounmap(tw_dev->base_addr);
1745
1746        /* Free up the mem region */
1747        pci_release_regions(pdev);
1748
1749        /* Free up device extension resources */
1750        twl_free_device_extension(tw_dev);
1751
1752        scsi_host_put(tw_dev->host);
1753        pci_disable_device(pdev);
1754        twl_device_extension_count--;
1755} /* End twl_remove() */
1756
1757#ifdef CONFIG_PM
1758/* This function is called on PCI suspend */
1759static int twl_suspend(struct pci_dev *pdev, pm_message_t state)
1760{
1761        struct Scsi_Host *host = pci_get_drvdata(pdev);
1762        TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata;
1763
1764        printk(KERN_WARNING "3w-sas: Suspending host %d.\n", tw_dev->host->host_no);
1765        /* Disable interrupts */
1766        TWL_MASK_INTERRUPTS(tw_dev);
1767
1768        free_irq(tw_dev->tw_pci_dev->irq, tw_dev);
1769
1770        /* Tell the card we are shutting down */
1771        if (twl_initconnection(tw_dev, 1, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL)) {
1772                TW_PRINTK(tw_dev->host, TW_DRIVER, 0x23, "Connection shutdown failed during suspend");
1773        } else {
1774                printk(KERN_WARNING "3w-sas: Suspend complete.\n");
1775        }
1776
1777        /* Clear doorbell interrupt */
1778        TWL_CLEAR_DB_INTERRUPT(tw_dev);
1779
1780        pci_save_state(pdev);
1781        pci_disable_device(pdev);
1782        pci_set_power_state(pdev, pci_choose_state(pdev, state));
1783
1784        return 0;
1785} /* End twl_suspend() */
1786
1787/* This function is called on PCI resume */
1788static int twl_resume(struct pci_dev *pdev)
1789{
1790        int retval = 0;
1791        struct Scsi_Host *host = pci_get_drvdata(pdev);
1792        TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata;
1793
1794        printk(KERN_WARNING "3w-sas: Resuming host %d.\n", tw_dev->host->host_no);
1795        pci_set_power_state(pdev, PCI_D0);
1796        pci_enable_wake(pdev, PCI_D0, 0);
1797        pci_restore_state(pdev);
1798
1799        retval = pci_enable_device(pdev);
1800        if (retval) {
1801                TW_PRINTK(tw_dev->host, TW_DRIVER, 0x24, "Enable device failed during resume");
1802                return retval;
1803        }
1804
1805        pci_set_master(pdev);
1806        pci_try_set_mwi(pdev);
1807
1808        if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64))
1809            || pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)))
1810                if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32))
1811                    || pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) {
1812                        TW_PRINTK(host, TW_DRIVER, 0x25, "Failed to set dma mask during resume");
1813                        retval = -ENODEV;
1814                        goto out_disable_device;
1815                }
1816
1817        /* Initialize the card */
1818        if (twl_reset_sequence(tw_dev, 0)) {
1819                retval = -ENODEV;
1820                goto out_disable_device;
1821        }
1822
1823        /* Now setup the interrupt handler */
1824        retval = request_irq(pdev->irq, twl_interrupt, IRQF_SHARED, "3w-sas", tw_dev);
1825        if (retval) {
1826                TW_PRINTK(tw_dev->host, TW_DRIVER, 0x26, "Error requesting IRQ during resume");
1827                retval = -ENODEV;
1828                goto out_disable_device;
1829        }
1830
1831        /* Now enable MSI if enabled */
1832        if (test_bit(TW_USING_MSI, &tw_dev->flags))
1833                pci_enable_msi(pdev);
1834
1835        /* Re-enable interrupts on the card */
1836        TWL_UNMASK_INTERRUPTS(tw_dev);
1837
1838        printk(KERN_WARNING "3w-sas: Resume complete.\n");
1839        return 0;
1840
1841out_disable_device:
1842        scsi_remove_host(host);
1843        pci_disable_device(pdev);
1844
1845        return retval;
1846} /* End twl_resume() */
1847#endif
1848
1849/* PCI Devices supported by this driver */
1850static struct pci_device_id twl_pci_tbl[] = {
1851        { PCI_VDEVICE(3WARE, PCI_DEVICE_ID_3WARE_9750) },
1852        { }
1853};
1854MODULE_DEVICE_TABLE(pci, twl_pci_tbl);
1855
1856/* pci_driver initializer */
1857static struct pci_driver twl_driver = {
1858        .name           = "3w-sas",
1859        .id_table       = twl_pci_tbl,
1860        .probe          = twl_probe,
1861        .remove         = twl_remove,
1862#ifdef CONFIG_PM
1863        .suspend        = twl_suspend,
1864        .resume         = twl_resume,
1865#endif
1866        .shutdown       = twl_shutdown
1867};
1868
1869/* This function is called on driver initialization */
1870static int __init twl_init(void)
1871{
1872        printk(KERN_INFO "LSI 3ware SAS/SATA-RAID Controller device driver for Linux v%s.\n", TW_DRIVER_VERSION);
1873
1874        return pci_register_driver(&twl_driver);
1875} /* End twl_init() */
1876
1877/* This function is called on driver exit */
1878static void __exit twl_exit(void)
1879{
1880        pci_unregister_driver(&twl_driver);
1881} /* End twl_exit() */
1882
1883module_init(twl_init);
1884module_exit(twl_exit);
1885
1886