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