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