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