Merge master.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6
authorLinus Torvalds <torvalds@woody.linux-foundation.org>
Sun, 22 Jul 2007 18:36:49 +0000 (11:36 -0700)
committerLinus Torvalds <torvalds@woody.linux-foundation.org>
Sun, 22 Jul 2007 18:36:49 +0000 (11:36 -0700)
* master.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6: (60 commits)
  [SCSI] libsas: make ATA functions selectable by a config option
  [SCSI] bsg: unexport sg v3 helper functions
  [SCSI] bsg: fix bsg_unregister_queue
  [SCSI] bsg: make class backlinks
  [SCSI] 3w-9xxx: add support for 9690SA
  [SCSI] bsg: fix bsg_register_queue error path
  [SCSI] ESP: Increase ESP_BUS_TIMEOUT to 275.
  [SCSI] libsas: fix scr_read/write users and update the libata documentation
  [SCSI] mpt fusion: update Kconfig help
  [SCSI] scsi_transport_sas: add destructor for bsg
  [SCSI] iscsi_tcp: buggered kmalloc()
  [SCSI] qla2xxx: Update version number to 8.02.00-k2.
  [SCSI] qla2xxx: Add ISP25XX support.
  [SCSI] qla2xxx: Use pci_try_set_mwi().
  [SCSI] qla2xxx: Use PCI-X/PCI-Express read control interfaces.
  [SCSI] qla2xxx: Re-factor isp_operations to static structures.
  [SCSI] qla2xxx: Validate mid-layer 'underflow' during check-condition handling.
  [SCSI] qla2xxx: Correct setting of 'current' and 'supported' speeds during FDMI registration.
  [SCSI] qla2xxx: Generalize iIDMA support.
  [SCSI] qla2xxx: Generalize FW-Interface-2 support.
  ...

12 files changed:
1  2 
block/bsg.c
block/scsi_ioctl.c
drivers/firewire/fw-sbp2.c
drivers/s390/scsi/zfcp_aux.c
drivers/scsi/3w-9xxx.c
drivers/scsi/Kconfig
drivers/scsi/aic94xx/aic94xx_init.c
drivers/scsi/libsas/sas_init.c
drivers/scsi/qla2xxx/qla_os.c
drivers/scsi/sim710.c
include/linux/libata.h
include/linux/pci_ids.h

diff --combined block/bsg.c
@@@ -932,24 -932,34 +932,34 @@@ void bsg_unregister_queue(struct reques
  {
        struct bsg_class_device *bcd = &q->bsg_dev;
  
-       WARN_ON(!bcd->class_dev);
+       if (!bcd->class_dev)
+               return;
  
        mutex_lock(&bsg_mutex);
        sysfs_remove_link(&q->kobj, "bsg");
-       class_device_destroy(bsg_class, MKDEV(bsg_major, bcd->minor));
+       class_device_unregister(bcd->class_dev);
+       put_device(bcd->dev);
        bcd->class_dev = NULL;
+       bcd->dev = NULL;
        list_del_init(&bcd->list);
        bsg_device_nr--;
        mutex_unlock(&bsg_mutex);
  }
  EXPORT_SYMBOL_GPL(bsg_unregister_queue);
  
- int bsg_register_queue(struct request_queue *q, const char *name)
+ int bsg_register_queue(struct request_queue *q, struct device *gdev,
+                      const char *name)
  {
        struct bsg_class_device *bcd, *__bcd;
        dev_t dev;
        int ret = -EMFILE;
        struct class_device *class_dev = NULL;
+       const char *devname;
+       if (name)
+               devname = name;
+       else
+               devname = gdev->bus_id;
  
        /*
         * we need a proper transport to send commands, not a stacked device
@@@ -982,18 -992,20 +992,20 @@@ retry
                bsg_minor_idx = 0;
  
        bcd->queue = q;
+       bcd->dev = get_device(gdev);
        dev = MKDEV(bsg_major, bcd->minor);
-       class_dev = class_device_create(bsg_class, NULL, dev, bcd->dev, "%s", name);
+       class_dev = class_device_create(bsg_class, NULL, dev, gdev, "%s",
+                                       devname);
        if (IS_ERR(class_dev)) {
                ret = PTR_ERR(class_dev);
-               goto err;
+               goto err_put;
        }
        bcd->class_dev = class_dev;
  
        if (q->kobj.sd) {
                ret = sysfs_create_link(&q->kobj, &bcd->class_dev->kobj, "bsg");
                if (ret)
-                       goto err;
+                       goto err_unregister;
        }
  
        list_add_tail(&bcd->list, &bsg_class_list);
  
        mutex_unlock(&bsg_mutex);
        return 0;
+ err_unregister:
+       class_device_unregister(class_dev);
+ err_put:
+       put_device(gdev);
  err:
-       if (class_dev)
-               class_device_destroy(bsg_class, MKDEV(bsg_major, bcd->minor));
        mutex_unlock(&bsg_mutex);
        return ret;
  }
  EXPORT_SYMBOL_GPL(bsg_register_queue);
  
- static int bsg_add(struct class_device *cl_dev, struct class_interface *cl_intf)
- {
-       int ret;
-       struct scsi_device *sdp = to_scsi_device(cl_dev->dev);
-       struct request_queue *rq = sdp->request_queue;
-       if (rq->kobj.parent)
-               ret = bsg_register_queue(rq, kobject_name(rq->kobj.parent));
-       else
-               ret = bsg_register_queue(rq, kobject_name(&sdp->sdev_gendev.kobj));
-       return ret;
- }
- static void bsg_remove(struct class_device *cl_dev, struct class_interface *cl_intf)
- {
-       bsg_unregister_queue(to_scsi_device(cl_dev->dev)->request_queue);
- }
- static struct class_interface bsg_intf = {
-       .add    = bsg_add,
-       .remove = bsg_remove,
- };
  static struct cdev bsg_cdev = {
        .kobj   = {.name = "bsg", },
        .owner  = THIS_MODULE,
@@@ -1043,7 -1035,7 +1035,7 @@@ static int __init bsg_init(void
        dev_t devid;
  
        bsg_cmd_cachep = kmem_cache_create("bsg_cmd",
 -                              sizeof(struct bsg_command), 0, 0, NULL, NULL);
 +                              sizeof(struct bsg_command), 0, 0, NULL);
        if (!bsg_cmd_cachep) {
                printk(KERN_ERR "bsg: failed creating slab cache\n");
                return -ENOMEM;
        if (ret)
                goto unregister_chrdev;
  
-       ret = scsi_register_interface(&bsg_intf);
-       if (ret)
-               goto remove_cdev;
        printk(KERN_INFO BSG_DESCRIPTION " version " BSG_VERSION
               " loaded (major %d)\n", bsg_major);
        return 0;
- remove_cdev:
-       printk(KERN_ERR "bsg: failed register scsi interface %d\n", ret);
-       cdev_del(&bsg_cdev);
  unregister_chrdev:
        unregister_chrdev_region(MKDEV(bsg_major, 0), BSG_MAX_DEVS);
  destroy_bsg_class:
diff --combined block/scsi_ioctl.c
@@@ -214,8 -214,8 +214,8 @@@ int blk_verify_command(unsigned char *c
  }
  EXPORT_SYMBOL_GPL(blk_verify_command);
  
- int blk_fill_sghdr_rq(request_queue_t *q, struct request *rq,
-                     struct sg_io_hdr *hdr, int has_write_perm)
static int blk_fill_sghdr_rq(request_queue_t *q, struct request *rq,
+                            struct sg_io_hdr *hdr, int has_write_perm)
  {
        memset(rq->cmd, 0, BLK_MAX_CDB); /* ATAPI hates garbage after CDB */
  
  
        return 0;
  }
- EXPORT_SYMBOL_GPL(blk_fill_sghdr_rq);
  
  /*
   * unmap a request that was previously mapped to this sg_io_hdr. handles
   * both sg and non-sg sg_io_hdr.
   */
- int blk_unmap_sghdr_rq(struct request *rq, struct sg_io_hdr *hdr)
static int blk_unmap_sghdr_rq(struct request *rq, struct sg_io_hdr *hdr)
  {
        blk_rq_unmap_user(rq->bio);
        blk_put_request(rq);
        return 0;
  }
- EXPORT_SYMBOL_GPL(blk_unmap_sghdr_rq);
  
- int blk_complete_sghdr_rq(struct request *rq, struct sg_io_hdr *hdr,
-                         struct bio *bio)
static int blk_complete_sghdr_rq(struct request *rq, struct sg_io_hdr *hdr,
+                                struct bio *bio)
  {
        int r, ret = 0;
  
  
        return r;
  }
- EXPORT_SYMBOL_GPL(blk_complete_sghdr_rq);
  
  static int sg_io(struct file *file, request_queue_t *q,
                struct gendisk *bd_disk, struct sg_io_hdr *hdr)
@@@ -436,10 -433,11 +433,10 @@@ int sg_scsi_ioctl(struct file *file, st
  
        bytes = max(in_len, out_len);
        if (bytes) {
 -              buffer = kmalloc(bytes, q->bounce_gfp | GFP_USER| __GFP_NOWARN);
 +              buffer = kzalloc(bytes, q->bounce_gfp | GFP_USER| __GFP_NOWARN);
                if (!buffer)
                        return -ENOMEM;
  
 -              memset(buffer, 0, bytes);
        }
  
        rq = blk_get_request(q, in_len ? WRITE : READ, __GFP_WAIT);
@@@ -840,6 -840,7 +840,6 @@@ complete_command_orb(struct sbp2_orb *b
                container_of(base_orb, struct sbp2_command_orb, base);
        struct fw_unit *unit = orb->unit;
        struct fw_device *device = fw_device(unit->device.parent);
 -      struct scatterlist *sg;
        int result;
  
        if (status != NULL) {
        dma_unmap_single(device->card->device, orb->base.request_bus,
                         sizeof(orb->request), DMA_TO_DEVICE);
  
 -      if (orb->cmd->use_sg > 0) {
 -              sg = (struct scatterlist *)orb->cmd->request_buffer;
 -              dma_unmap_sg(device->card->device, sg, orb->cmd->use_sg,
 +      if (scsi_sg_count(orb->cmd) > 0)
 +              dma_unmap_sg(device->card->device, scsi_sglist(orb->cmd),
 +                           scsi_sg_count(orb->cmd),
                             orb->cmd->sc_data_direction);
 -      }
  
        if (orb->page_table_bus != 0)
                dma_unmap_single(device->card->device, orb->page_table_bus,
@@@ -899,8 -901,8 +899,8 @@@ static int sbp2_command_orb_map_scatter
        int sg_len, l, i, j, count;
        dma_addr_t sg_addr;
  
 -      sg = (struct scatterlist *)orb->cmd->request_buffer;
 -      count = dma_map_sg(device->card->device, sg, orb->cmd->use_sg,
 +      sg = scsi_sglist(orb->cmd);
 +      count = dma_map_sg(device->card->device, sg, scsi_sg_count(orb->cmd),
                           orb->cmd->sc_data_direction);
        if (count == 0)
                goto fail;
        return 0;
  
   fail_page_table:
 -      dma_unmap_sg(device->card->device, sg, orb->cmd->use_sg,
 +      dma_unmap_sg(device->card->device, sg, scsi_sg_count(orb->cmd),
                     orb->cmd->sc_data_direction);
   fail:
        return -ENOMEM;
@@@ -1029,7 -1031,7 +1029,7 @@@ static int sbp2_scsi_queuecommand(struc
                orb->request.misc |=
                        COMMAND_ORB_DIRECTION(SBP2_DIRECTION_TO_MEDIA);
  
 -      if (cmd->use_sg && sbp2_command_orb_map_scatterlist(orb) < 0)
 +      if (scsi_sg_count(cmd) && sbp2_command_orb_map_scatterlist(orb) < 0)
                goto fail_mapping;
  
        fw_memcpy_to_be32(&orb->request, &orb->request, sizeof(orb->request));
@@@ -1160,7 -1162,7 +1160,7 @@@ static struct device_attribute *sbp2_sc
  static struct scsi_host_template scsi_driver_template = {
        .module                 = THIS_MODULE,
        .name                   = "SBP-2 IEEE-1394",
-       .proc_name              = (char *)sbp2_driver_name,
+       .proc_name              = sbp2_driver_name,
        .queuecommand           = sbp2_scsi_queuecommand,
        .slave_alloc            = sbp2_scsi_slave_alloc,
        .slave_configure        = sbp2_scsi_slave_configure,
@@@ -259,21 -259,21 +259,21 @@@ zfcp_module_init(void
        size = sizeof(struct zfcp_fsf_req_qtcb);
        align = calc_alignment(size);
        zfcp_data.fsf_req_qtcb_cache =
 -              kmem_cache_create("zfcp_fsf", size, align, 0, NULL, NULL);
 +              kmem_cache_create("zfcp_fsf", size, align, 0, NULL);
        if (!zfcp_data.fsf_req_qtcb_cache)
                goto out;
  
        size = sizeof(struct fsf_status_read_buffer);
        align = calc_alignment(size);
        zfcp_data.sr_buffer_cache =
 -              kmem_cache_create("zfcp_sr", size, align, 0, NULL, NULL);
 +              kmem_cache_create("zfcp_sr", size, align, 0, NULL);
        if (!zfcp_data.sr_buffer_cache)
                goto out_sr_cache;
  
        size = sizeof(struct zfcp_gid_pn_data);
        align = calc_alignment(size);
        zfcp_data.gid_pn_cache =
 -              kmem_cache_create("zfcp_gid", size, align, 0, NULL, NULL);
 +              kmem_cache_create("zfcp_gid", size, align, 0, NULL);
        if (!zfcp_data.gid_pn_cache)
                goto out_gid_cache;
  
@@@ -1526,15 -1526,12 +1526,12 @@@ zfcp_gid_pn_buffers_alloc(struct zfcp_g
   * zfcp_gid_pn_buffers_free - free buffers for GID_PN nameserver request
   * @gid_pn: pointer to struct zfcp_gid_pn_data which has to be freed
   */
- static void
- zfcp_gid_pn_buffers_free(struct zfcp_gid_pn_data *gid_pn)
+ static void zfcp_gid_pn_buffers_free(struct zfcp_gid_pn_data *gid_pn)
  {
-         if ((gid_pn->ct.pool != 0))
+       if (gid_pn->ct.pool)
                mempool_free(gid_pn, gid_pn->ct.pool);
        else
-                 kfree(gid_pn);
-       return;
+               kfree(gid_pn);
  }
  
  /**
diff --combined drivers/scsi/3w-9xxx.c
@@@ -4,7 -4,7 +4,7 @@@
     Written By: Adam Radford <linuxraid@amcc.com>
     Modifications By: Tom Couch <linuxraid@amcc.com>
  
-    Copyright (C) 2004-2006 Applied Micro Circuits Corporation.
+    Copyright (C) 2004-2007 Applied Micro Circuits Corporation.
  
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@@ -69,6 -69,8 +69,8 @@@
     2.26.02.008 - Free irq handler in __twa_shutdown().
                   Serialize reset code.
                   Add support for 9650SE controllers.
+    2.26.02.009 - Fix dma mask setting to fallback to 32-bit if 64-bit fails.
+    2.26.02.010 - Add support for 9690SA controllers.
  */
  
  #include <linux/module.h>
@@@ -92,7 -94,7 +94,7 @@@
  #include "3w-9xxx.h"
  
  /* Globals */
- #define TW_DRIVER_VERSION "2.26.02.008"
+ #define TW_DRIVER_VERSION "2.26.02.010"
  static TW_Device_Extension *twa_device_extension_list[TW_MAX_SLOT];
  static unsigned int twa_device_extension_count;
  static int twa_major = -1;
@@@ -124,11 -126,11 +126,11 @@@ static int twa_initconnection(TW_Device
                              unsigned short *fw_on_ctlr_branch, 
                              unsigned short *fw_on_ctlr_build, 
                              u32 *init_connect_result);
- static void twa_load_sgl(TW_Command_Full *full_command_packet, int request_id, dma_addr_t dma_handle, int length);
+ static void twa_load_sgl(TW_Device_Extension *tw_dev, TW_Command_Full *full_command_packet, int request_id, dma_addr_t dma_handle, int length);
  static int twa_poll_response(TW_Device_Extension *tw_dev, int request_id, int seconds);
  static int twa_poll_status_gone(TW_Device_Extension *tw_dev, u32 flag, int seconds);
  static int twa_post_command_packet(TW_Device_Extension *tw_dev, int request_id, char internal);
- static int twa_reset_device_extension(TW_Device_Extension *tw_dev, int ioctl_reset);
+ static int twa_reset_device_extension(TW_Device_Extension *tw_dev);
  static int twa_reset_sequence(TW_Device_Extension *tw_dev, int soft_reset);
  static int twa_scsiop_execute_scsi(TW_Device_Extension *tw_dev, int request_id, char *cdb, int use_sg, TW_SG_Entry *sglistarg);
  static void twa_scsiop_execute_scsi_complete(TW_Device_Extension *tw_dev, int request_id);
@@@ -683,7 -685,7 +685,7 @@@ static int twa_chrdev_ioctl(struct inod
                full_command_packet = &tw_ioctl->firmware_command;
  
                /* Load request id and sglist for both command types */
-               twa_load_sgl(full_command_packet, request_id, dma_handle, data_buffer_length_adjusted);
+               twa_load_sgl(tw_dev, full_command_packet, request_id, dma_handle, data_buffer_length_adjusted);
  
                memcpy(tw_dev->command_packet_virt[request_id], &(tw_ioctl->firmware_command), sizeof(TW_Command_Full));
  
                if (tw_dev->chrdev_request_id != TW_IOCTL_CHRDEV_FREE) {
                        /* Now we need to reset the board */
                        printk(KERN_WARNING "3w-9xxx: scsi%d: WARNING: (0x%02X:0x%04X): Character ioctl (0x%x) timed out, resetting card.\n",
-                              tw_dev->host->host_no, TW_DRIVER, 0xc,
+                              tw_dev->host->host_no, TW_DRIVER, 0x37,
                               cmd);
                        retval = TW_IOCTL_ERROR_OS_EIO;
-                       twa_reset_device_extension(tw_dev, 1);
+                       twa_reset_device_extension(tw_dev);
                        goto out3;
                }
  
@@@ -890,7 -892,9 +892,9 @@@ static int twa_decode_bits(TW_Device_Ex
        }
  
        if (status_reg_value & TW_STATUS_QUEUE_ERROR) {
-               if ((tw_dev->tw_pci_dev->device != PCI_DEVICE_ID_3WARE_9650SE) || (!test_bit(TW_IN_RESET, &tw_dev->flags)))
+               if (((tw_dev->tw_pci_dev->device != PCI_DEVICE_ID_3WARE_9650SE) &&
+                    (tw_dev->tw_pci_dev->device != PCI_DEVICE_ID_3WARE_9690SA)) ||
+                   (!test_bit(TW_IN_RESET, &tw_dev->flags)))
                        TW_PRINTK(tw_dev->host, TW_DRIVER, 0xe, "Controller Queue Error: clearing");
                writel(TW_CONTROL_CLEAR_QUEUE_ERROR, TW_CONTROL_REG_ADDR(tw_dev));
        }
@@@ -935,8 -939,7 +939,7 @@@ static int twa_empty_response_queue_lar
        unsigned long before;
        int retval = 1;
  
-       if ((tw_dev->tw_pci_dev->device == PCI_DEVICE_ID_3WARE_9550SX) ||
-           (tw_dev->tw_pci_dev->device == PCI_DEVICE_ID_3WARE_9650SE)) {
+       if (tw_dev->tw_pci_dev->device != PCI_DEVICE_ID_3WARE_9000) {
                before = jiffies;
                while ((response_que_value & TW_9550SX_DRAIN_COMPLETED) != TW_9550SX_DRAIN_COMPLETED) {
                        response_que_value = readl(TW_RESPONSE_QUEUE_REG_ADDR_LARGE(tw_dev));
@@@ -1160,12 -1163,13 +1163,12 @@@ static int twa_initialize_device_extens
        }
  
        /* Allocate event info space */
 -      tw_dev->event_queue[0] = kmalloc(sizeof(TW_Event) * TW_Q_LENGTH, GFP_KERNEL);
 +      tw_dev->event_queue[0] = kcalloc(TW_Q_LENGTH, sizeof(TW_Event), GFP_KERNEL);
        if (!tw_dev->event_queue[0]) {
                TW_PRINTK(tw_dev->host, TW_DRIVER, 0x18, "Event info memory allocation failed");
                goto out;
        }
  
 -      memset(tw_dev->event_queue[0], 0, sizeof(TW_Event) * TW_Q_LENGTH);
  
        for (i = 0; i < TW_Q_LENGTH; i++) {
                tw_dev->event_queue[i] = (TW_Event *)((unsigned char *)tw_dev->event_queue[0] + (i * sizeof(TW_Event)));
@@@ -1195,7 -1199,6 +1198,6 @@@ static irqreturn_t twa_interrupt(int ir
        u32 status_reg_value;
        TW_Response_Queue response_que;
        TW_Command_Full *full_command_packet;
-       TW_Command *command_packet;
        TW_Device_Extension *tw_dev = (TW_Device_Extension *)dev_instance;
        int handled = 0;
  
                        request_id = TW_RESID_OUT(response_que.response_id);
                        full_command_packet = tw_dev->command_packet_virt[request_id];
                        error = 0;
-                       command_packet = &full_command_packet->command.oldcommand;
                        /* Check for command packet errors */
                        if (full_command_packet->command.newcommand.status != 0) {
                                if (tw_dev->srb[request_id] != 0) {
@@@ -1352,11 -1354,15 +1353,15 @@@ twa_interrupt_bail
  } /* End twa_interrupt() */
  
  /* This function will load the request id and various sgls for ioctls */
- static void twa_load_sgl(TW_Command_Full *full_command_packet, int request_id, dma_addr_t dma_handle, int length)
+ static void twa_load_sgl(TW_Device_Extension *tw_dev, TW_Command_Full *full_command_packet, int request_id, dma_addr_t dma_handle, int length)
  {
        TW_Command *oldcommand;
        TW_Command_Apache *newcommand;
        TW_SG_Entry *sgl;
+       unsigned int pae = 0;
+       if ((sizeof(long) < 8) && (sizeof(dma_addr_t) > 4))
+               pae = 1;
  
        if (TW_OP_OUT(full_command_packet->command.newcommand.opcode__reserved) == TW_OP_EXECUTE_SCSI) {
                newcommand = &full_command_packet->command.newcommand;
  
                if (TW_SGL_OUT(oldcommand->opcode__sgloffset)) {
                        /* Load the sg list */
-                       sgl = (TW_SG_Entry *)((u32 *)oldcommand+TW_SGL_OUT(oldcommand->opcode__sgloffset));
+                       if (tw_dev->tw_pci_dev->device == PCI_DEVICE_ID_3WARE_9690SA)
+                               sgl = (TW_SG_Entry *)((u32 *)oldcommand+oldcommand->size - (sizeof(TW_SG_Entry)/4) + pae);
+                       else
+                               sgl = (TW_SG_Entry *)((u32 *)oldcommand+TW_SGL_OUT(oldcommand->opcode__sgloffset));
                        sgl->address = TW_CPU_TO_SGL(dma_handle + sizeof(TW_Ioctl_Buf_Apache) - 1);
                        sgl->length = cpu_to_le32(length);
  
-                       if ((sizeof(long) < 8) && (sizeof(dma_addr_t) > 4))
-                               oldcommand->size += 1;
+                       oldcommand->size += pae;
                }
        }
  } /* End twa_load_sgl() */
@@@ -1506,7 -1514,8 +1513,8 @@@ static int twa_post_command_packet(TW_D
        command_que_value = tw_dev->command_packet_phys[request_id];
  
        /* For 9650SE write low 4 bytes first */
-       if (tw_dev->tw_pci_dev->device == PCI_DEVICE_ID_3WARE_9650SE) {
+       if ((tw_dev->tw_pci_dev->device == PCI_DEVICE_ID_3WARE_9650SE) ||
+           (tw_dev->tw_pci_dev->device == PCI_DEVICE_ID_3WARE_9690SA)) {
                command_que_value += TW_COMMAND_OFFSET;
                writel((u32)command_que_value, TW_COMMAND_QUEUE_REG_ADDR_LARGE(tw_dev));
        }
                TW_UNMASK_COMMAND_INTERRUPT(tw_dev);
                goto out;
        } else {
-               if (tw_dev->tw_pci_dev->device == PCI_DEVICE_ID_3WARE_9650SE) {
+               if ((tw_dev->tw_pci_dev->device == PCI_DEVICE_ID_3WARE_9650SE) ||
+                   (tw_dev->tw_pci_dev->device == PCI_DEVICE_ID_3WARE_9690SA)) {
                        /* Now write upper 4 bytes */
                        writel((u32)((u64)command_que_value >> 32), TW_COMMAND_QUEUE_REG_ADDR_LARGE(tw_dev) + 0x4);
                } else {
@@@ -1561,7 -1571,7 +1570,7 @@@ out
  } /* End twa_post_command_packet() */
  
  /* This function will reset a device extension */
- static int twa_reset_device_extension(TW_Device_Extension *tw_dev, int ioctl_reset)
+ static int twa_reset_device_extension(TW_Device_Extension *tw_dev)
  {
        int i = 0;
        int retval = 1;
@@@ -1719,7 -1729,7 +1728,7 @@@ static int twa_scsi_eh_reset(struct scs
        mutex_lock(&tw_dev->ioctl_lock);
  
        /* Now reset the card and some of the device extension data */
-       if (twa_reset_device_extension(tw_dev, 0)) {
+       if (twa_reset_device_extension(tw_dev)) {
                TW_PRINTK(tw_dev->host, TW_DRIVER, 0x2b, "Controller reset failed during scsi host reset");
                goto out;
        }
@@@ -2001,11 -2011,14 +2010,14 @@@ static int __devinit twa_probe(struct p
  
        pci_set_master(pdev);
  
-       retval = pci_set_dma_mask(pdev, sizeof(dma_addr_t) > 4 ? DMA_64BIT_MASK : DMA_32BIT_MASK);
-       if (retval) {
-               TW_PRINTK(host, TW_DRIVER, 0x23, "Failed to set dma mask");
-               goto out_disable_device;
-       }
+       if (pci_set_dma_mask(pdev, DMA_64BIT_MASK)
+           || pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK))
+               if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)
+                   || pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK)) {
+                       TW_PRINTK(host, TW_DRIVER, 0x23, "Failed to set dma mask");
+                       retval = -ENODEV;
+                       goto out_disable_device;
+               }
  
        host = scsi_host_alloc(&driver_template, sizeof(TW_Device_Extension));
        if (!host) {
                goto out_iounmap;
  
        /* Set host specific parameters */
-       if (pdev->device == PCI_DEVICE_ID_3WARE_9650SE)
+       if ((pdev->device == PCI_DEVICE_ID_3WARE_9650SE) ||
+           (pdev->device == PCI_DEVICE_ID_3WARE_9690SA))
                host->max_id = TW_MAX_UNITS_9650SE;
        else
                host->max_id = TW_MAX_UNITS;
@@@ -2160,6 -2174,8 +2173,8 @@@ static struct pci_device_id twa_pci_tbl
          PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
        { PCI_VENDOR_ID_3WARE, PCI_DEVICE_ID_3WARE_9650SE,
          PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+       { PCI_VENDOR_ID_3WARE, PCI_DEVICE_ID_3WARE_9690SA,
+         PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
        { }
  };
  MODULE_DEVICE_TABLE(pci, twa_pci_tbl);
diff --combined drivers/scsi/Kconfig
@@@ -282,7 -282,7 +282,7 @@@ config SCSI_ISCSI_ATTR
  
  config SCSI_SAS_ATTRS
        tristate "SAS Transport Attributes"
-       depends on SCSI
+       depends on SCSI && BLK_DEV_BSG
        help
          If you wish to export transport-specific information about
          each attached SAS device to sysfs, say Y.
@@@ -291,8 -291,12 +291,12 @@@ source "drivers/scsi/libsas/Kconfig
  
  endmenu
  
- menu "SCSI low-level drivers"
+ menuconfig SCSI_LOWLEVEL
+       bool "SCSI low-level drivers"
        depends on SCSI!=n
+       default y
+ if SCSI_LOWLEVEL
  
  config ISCSI_TCP
        tristate "iSCSI Initiator over TCP/IP"
@@@ -483,7 -487,7 +487,7 @@@ source "drivers/scsi/aic94xx/Kconfig
  # All the I2O code and drivers do not seem to be 64bit safe.
  config SCSI_DPT_I2O
        tristate "Adaptec I2O RAID support "
 -      depends on !64BIT && SCSI && PCI
 +      depends on !64BIT && SCSI && PCI && VIRT_TO_BUS
        help
          This driver supports all of Adaptec's I2O based RAID controllers as 
          well as the DPT SmartRaid V cards.  This is an Adaptec maintained
@@@ -1800,7 -1804,7 +1804,7 @@@ config SCSI_SR
          To compile this driver as a module, choose M here: the
          module will be called libsrp.
  
- endmenu
+ endif # SCSI_LOWLEVEL
  
  source "drivers/scsi/pcmcia/Kconfig"
  
@@@ -81,6 -81,9 +81,9 @@@ static struct scsi_host_template aic94x
        .use_clustering         = ENABLE_CLUSTERING,
        .eh_device_reset_handler        = sas_eh_device_reset_handler,
        .eh_bus_reset_handler   = sas_eh_bus_reset_handler,
+       .slave_alloc            = sas_slave_alloc,
+       .target_destroy         = sas_target_destroy,
+       .ioctl                  = sas_ioctl,
  };
  
  static int __devinit asd_map_memio(struct asd_ha_struct *asd_ha)
@@@ -462,7 -465,7 +465,7 @@@ static int asd_create_global_caches(voi
                                            sizeof(struct asd_dma_tok),
                                            0,
                                            SLAB_HWCACHE_ALIGN,
 -                                          NULL, NULL);
 +                                          NULL);
                if (!asd_dma_token_cache) {
                        asd_printk("couldn't create dma token cache\n");
                        return -ENOMEM;
                                                   sizeof(struct asd_ascb),
                                                   0,
                                                   SLAB_HWCACHE_ALIGN,
 -                                                 NULL, NULL);
 +                                                 NULL);
                if (!asd_ascb_cache) {
                        asd_printk("couldn't create ascb cache\n");
                        goto Err;
@@@ -259,6 -259,7 +259,7 @@@ static struct sas_function_template sf
        .phy_reset = sas_phy_reset,
        .set_phy_speed = sas_set_phy_speed,
        .get_linkerrors = sas_get_linkerrors,
+       .smp_handler = sas_smp_handler,
  };
  
  struct scsi_transport_template *
@@@ -292,7 -293,7 +293,7 @@@ EXPORT_SYMBOL_GPL(sas_domain_release_tr
  static int __init sas_class_init(void)
  {
        sas_task_cache = kmem_cache_create("sas_task", sizeof(struct sas_task),
 -                                         0, SLAB_HWCACHE_ALIGN, NULL, NULL);
 +                                         0, SLAB_HWCACHE_ALIGN, NULL);
        if (!sas_task_cache)
                return -ENOMEM;
  
@@@ -265,6 -265,8 +265,8 @@@ qla24xx_pci_info_str(struct scsi_qla_ho
                strcpy(str, "PCIe (");
                if (lspeed == 1)
                        strcat(str, "2.5Gb/s ");
+               else if (lspeed == 2)
+                       strcat(str, "5.0Gb/s ");
                else
                        strcat(str, "<unknown> ");
                snprintf(lwstr, sizeof(lwstr), "x%d)", lwidth);
@@@ -343,6 -345,12 +345,12 @@@ qla24xx_fw_version_str(struct scsi_qla_
                strcat(str, "[IP] ");
        if (ha->fw_attributes & BIT_2)
                strcat(str, "[Multi-ID] ");
+       if (ha->fw_attributes & BIT_3)
+               strcat(str, "[SB-2] ");
+       if (ha->fw_attributes & BIT_4)
+               strcat(str, "[T10 CRC] ");
+       if (ha->fw_attributes & BIT_5)
+               strcat(str, "[VI] ");
        if (ha->fw_attributes & BIT_13)
                strcat(str, "[Experimental]");
        return str;
@@@ -681,7 -689,7 +689,7 @@@ qla2xxx_eh_abort(struct scsi_cmnd *cmd
                DEBUG3(qla2x00_print_scsi_cmd(cmd));
  
                spin_unlock_irqrestore(&pha->hardware_lock, flags);
-               if (ha->isp_ops.abort_command(ha, sp)) {
+               if (ha->isp_ops->abort_command(ha, sp)) {
                        DEBUG2(printk("%s(%ld): abort_command "
                            "mbx failed.\n", __func__, ha->host_no));
                } else {
@@@ -813,7 -821,7 +821,7 @@@ qla2xxx_eh_device_reset(struct scsi_cmn
  #if defined(LOGOUT_AFTER_DEVICE_RESET)
                if (ret == SUCCESS) {
                        if (fcport->flags & FC_FABRIC_DEVICE) {
-                               ha->isp_ops.fabric_logout(ha, fcport->loop_id);
+                               ha->isp_ops->fabric_logout(ha, fcport->loop_id);
                                qla2x00_mark_device_lost(ha, fcport, 0, 0);
                        }
                }
@@@ -1105,7 -1113,7 +1113,7 @@@ static in
  qla2x00_device_reset(scsi_qla_host_t *ha, fc_port_t *reset_fcport)
  {
        /* Abort Target command will clear Reservation */
-       return ha->isp_ops.abort_target(reset_fcport);
+       return ha->isp_ops->abort_target(reset_fcport);
  }
  
  static int
@@@ -1184,8 -1192,8 +1192,8 @@@ qla2x00_config_dma_addressing(scsi_qla_
                    !pci_set_consistent_dma_mask(ha->pdev, DMA_64BIT_MASK)) {
                        /* Ok, a 64bit DMA mask is applicable. */
                        ha->flags.enable_64bit_addressing = 1;
-                       ha->isp_ops.calc_req_entries = qla2x00_calc_iocbs_64;
-                       ha->isp_ops.build_iocbs = qla2x00_build_scsi_iocbs_64;
+                       ha->isp_ops->calc_req_entries = qla2x00_calc_iocbs_64;
+                       ha->isp_ops->build_iocbs = qla2x00_build_scsi_iocbs_64;
                        return;
                }
        }
        pci_set_consistent_dma_mask(ha->pdev, DMA_32BIT_MASK);
  }
  
+ static void
+ qla2x00_enable_intrs(scsi_qla_host_t *ha)
+ {
+       unsigned long flags = 0;
+       struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
+       spin_lock_irqsave(&ha->hardware_lock, flags);
+       ha->interrupts_on = 1;
+       /* enable risc and host interrupts */
+       WRT_REG_WORD(&reg->ictrl, ICR_EN_INT | ICR_EN_RISC);
+       RD_REG_WORD(&reg->ictrl);
+       spin_unlock_irqrestore(&ha->hardware_lock, flags);
+ }
+ static void
+ qla2x00_disable_intrs(scsi_qla_host_t *ha)
+ {
+       unsigned long flags = 0;
+       struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
+       spin_lock_irqsave(&ha->hardware_lock, flags);
+       ha->interrupts_on = 0;
+       /* disable risc and host interrupts */
+       WRT_REG_WORD(&reg->ictrl, 0);
+       RD_REG_WORD(&reg->ictrl);
+       spin_unlock_irqrestore(&ha->hardware_lock, flags);
+ }
+ static void
+ qla24xx_enable_intrs(scsi_qla_host_t *ha)
+ {
+       unsigned long flags = 0;
+       struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
+       spin_lock_irqsave(&ha->hardware_lock, flags);
+       ha->interrupts_on = 1;
+       WRT_REG_DWORD(&reg->ictrl, ICRX_EN_RISC_INT);
+       RD_REG_DWORD(&reg->ictrl);
+       spin_unlock_irqrestore(&ha->hardware_lock, flags);
+ }
+ static void
+ qla24xx_disable_intrs(scsi_qla_host_t *ha)
+ {
+       unsigned long flags = 0;
+       struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
+       spin_lock_irqsave(&ha->hardware_lock, flags);
+       ha->interrupts_on = 0;
+       WRT_REG_DWORD(&reg->ictrl, 0);
+       RD_REG_DWORD(&reg->ictrl);
+       spin_unlock_irqrestore(&ha->hardware_lock, flags);
+ }
+ static struct isp_operations qla2100_isp_ops = {
+       .pci_config             = qla2100_pci_config,
+       .reset_chip             = qla2x00_reset_chip,
+       .chip_diag              = qla2x00_chip_diag,
+       .config_rings           = qla2x00_config_rings,
+       .reset_adapter          = qla2x00_reset_adapter,
+       .nvram_config           = qla2x00_nvram_config,
+       .update_fw_options      = qla2x00_update_fw_options,
+       .load_risc              = qla2x00_load_risc,
+       .pci_info_str           = qla2x00_pci_info_str,
+       .fw_version_str         = qla2x00_fw_version_str,
+       .intr_handler           = qla2100_intr_handler,
+       .enable_intrs           = qla2x00_enable_intrs,
+       .disable_intrs          = qla2x00_disable_intrs,
+       .abort_command          = qla2x00_abort_command,
+       .abort_target           = qla2x00_abort_target,
+       .fabric_login           = qla2x00_login_fabric,
+       .fabric_logout          = qla2x00_fabric_logout,
+       .calc_req_entries       = qla2x00_calc_iocbs_32,
+       .build_iocbs            = qla2x00_build_scsi_iocbs_32,
+       .prep_ms_iocb           = qla2x00_prep_ms_iocb,
+       .prep_ms_fdmi_iocb      = qla2x00_prep_ms_fdmi_iocb,
+       .read_nvram             = qla2x00_read_nvram_data,
+       .write_nvram            = qla2x00_write_nvram_data,
+       .fw_dump                = qla2100_fw_dump,
+       .beacon_on              = NULL,
+       .beacon_off             = NULL,
+       .beacon_blink           = NULL,
+       .read_optrom            = qla2x00_read_optrom_data,
+       .write_optrom           = qla2x00_write_optrom_data,
+       .get_flash_version      = qla2x00_get_flash_version,
+ };
+ static struct isp_operations qla2300_isp_ops = {
+       .pci_config             = qla2300_pci_config,
+       .reset_chip             = qla2x00_reset_chip,
+       .chip_diag              = qla2x00_chip_diag,
+       .config_rings           = qla2x00_config_rings,
+       .reset_adapter          = qla2x00_reset_adapter,
+       .nvram_config           = qla2x00_nvram_config,
+       .update_fw_options      = qla2x00_update_fw_options,
+       .load_risc              = qla2x00_load_risc,
+       .pci_info_str           = qla2x00_pci_info_str,
+       .fw_version_str         = qla2x00_fw_version_str,
+       .intr_handler           = qla2300_intr_handler,
+       .enable_intrs           = qla2x00_enable_intrs,
+       .disable_intrs          = qla2x00_disable_intrs,
+       .abort_command          = qla2x00_abort_command,
+       .abort_target           = qla2x00_abort_target,
+       .fabric_login           = qla2x00_login_fabric,
+       .fabric_logout          = qla2x00_fabric_logout,
+       .calc_req_entries       = qla2x00_calc_iocbs_32,
+       .build_iocbs            = qla2x00_build_scsi_iocbs_32,
+       .prep_ms_iocb           = qla2x00_prep_ms_iocb,
+       .prep_ms_fdmi_iocb      = qla2x00_prep_ms_fdmi_iocb,
+       .read_nvram             = qla2x00_read_nvram_data,
+       .write_nvram            = qla2x00_write_nvram_data,
+       .fw_dump                = qla2300_fw_dump,
+       .beacon_on              = qla2x00_beacon_on,
+       .beacon_off             = qla2x00_beacon_off,
+       .beacon_blink           = qla2x00_beacon_blink,
+       .read_optrom            = qla2x00_read_optrom_data,
+       .write_optrom           = qla2x00_write_optrom_data,
+       .get_flash_version      = qla2x00_get_flash_version,
+ };
+ static struct isp_operations qla24xx_isp_ops = {
+       .pci_config             = qla24xx_pci_config,
+       .reset_chip             = qla24xx_reset_chip,
+       .chip_diag              = qla24xx_chip_diag,
+       .config_rings           = qla24xx_config_rings,
+       .reset_adapter          = qla24xx_reset_adapter,
+       .nvram_config           = qla24xx_nvram_config,
+       .update_fw_options      = qla24xx_update_fw_options,
+       .load_risc              = qla24xx_load_risc,
+       .pci_info_str           = qla24xx_pci_info_str,
+       .fw_version_str         = qla24xx_fw_version_str,
+       .intr_handler           = qla24xx_intr_handler,
+       .enable_intrs           = qla24xx_enable_intrs,
+       .disable_intrs          = qla24xx_disable_intrs,
+       .abort_command          = qla24xx_abort_command,
+       .abort_target           = qla24xx_abort_target,
+       .fabric_login           = qla24xx_login_fabric,
+       .fabric_logout          = qla24xx_fabric_logout,
+       .calc_req_entries       = NULL,
+       .build_iocbs            = NULL,
+       .prep_ms_iocb           = qla24xx_prep_ms_iocb,
+       .prep_ms_fdmi_iocb      = qla24xx_prep_ms_fdmi_iocb,
+       .read_nvram             = qla24xx_read_nvram_data,
+       .write_nvram            = qla24xx_write_nvram_data,
+       .fw_dump                = qla24xx_fw_dump,
+       .beacon_on              = qla24xx_beacon_on,
+       .beacon_off             = qla24xx_beacon_off,
+       .beacon_blink           = qla24xx_beacon_blink,
+       .read_optrom            = qla24xx_read_optrom_data,
+       .write_optrom           = qla24xx_write_optrom_data,
+       .get_flash_version      = qla24xx_get_flash_version,
+ };
+ static struct isp_operations qla25xx_isp_ops = {
+       .pci_config             = qla25xx_pci_config,
+       .reset_chip             = qla24xx_reset_chip,
+       .chip_diag              = qla24xx_chip_diag,
+       .config_rings           = qla24xx_config_rings,
+       .reset_adapter          = qla24xx_reset_adapter,
+       .nvram_config           = qla24xx_nvram_config,
+       .update_fw_options      = qla24xx_update_fw_options,
+       .load_risc              = qla24xx_load_risc,
+       .pci_info_str           = qla24xx_pci_info_str,
+       .fw_version_str         = qla24xx_fw_version_str,
+       .intr_handler           = qla24xx_intr_handler,
+       .enable_intrs           = qla24xx_enable_intrs,
+       .disable_intrs          = qla24xx_disable_intrs,
+       .abort_command          = qla24xx_abort_command,
+       .abort_target           = qla24xx_abort_target,
+       .fabric_login           = qla24xx_login_fabric,
+       .fabric_logout          = qla24xx_fabric_logout,
+       .calc_req_entries       = NULL,
+       .build_iocbs            = NULL,
+       .prep_ms_iocb           = qla24xx_prep_ms_iocb,
+       .prep_ms_fdmi_iocb      = qla24xx_prep_ms_fdmi_iocb,
+       .read_nvram             = qla25xx_read_nvram_data,
+       .write_nvram            = qla25xx_write_nvram_data,
+       .fw_dump                = qla25xx_fw_dump,
+       .beacon_on              = qla24xx_beacon_on,
+       .beacon_off             = qla24xx_beacon_off,
+       .beacon_blink           = qla24xx_beacon_blink,
+       .read_optrom            = qla24xx_read_optrom_data,
+       .write_optrom           = qla24xx_write_optrom_data,
+       .get_flash_version      = qla24xx_get_flash_version,
+ };
  static inline void
  qla2x00_set_isp_flags(scsi_qla_host_t *ha)
  {
        case PCI_DEVICE_ID_QLOGIC_ISP2422:
                ha->device_type |= DT_ISP2422;
                ha->device_type |= DT_ZIO_SUPPORTED;
+               ha->device_type |= DT_FWI2;
+               ha->device_type |= DT_IIDMA;
                ha->fw_srisc_address = RISC_START_ADDRESS_2400;
                break;
        case PCI_DEVICE_ID_QLOGIC_ISP2432:
                ha->device_type |= DT_ISP2432;
                ha->device_type |= DT_ZIO_SUPPORTED;
+               ha->device_type |= DT_FWI2;
+               ha->device_type |= DT_IIDMA;
                ha->fw_srisc_address = RISC_START_ADDRESS_2400;
                break;
        case PCI_DEVICE_ID_QLOGIC_ISP5422:
                ha->device_type |= DT_ISP5422;
+               ha->device_type |= DT_FWI2;
                ha->fw_srisc_address = RISC_START_ADDRESS_2400;
                break;
        case PCI_DEVICE_ID_QLOGIC_ISP5432:
                ha->device_type |= DT_ISP5432;
+               ha->device_type |= DT_FWI2;
+               ha->fw_srisc_address = RISC_START_ADDRESS_2400;
+               break;
+       case PCI_DEVICE_ID_QLOGIC_ISP2532:
+               ha->device_type |= DT_ISP2532;
+               ha->device_type |= DT_ZIO_SUPPORTED;
+               ha->device_type |= DT_FWI2;
+               ha->device_type |= DT_IIDMA;
                ha->fw_srisc_address = RISC_START_ADDRESS_2400;
                break;
        }
@@@ -1322,61 -1530,6 +1530,6 @@@ iospace_error_exit
        return (-ENOMEM);
  }
  
- static void
- qla2x00_enable_intrs(scsi_qla_host_t *ha)
- {
-       unsigned long flags = 0;
-       struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
-       spin_lock_irqsave(&ha->hardware_lock, flags);
-       ha->interrupts_on = 1;
-       /* enable risc and host interrupts */
-       WRT_REG_WORD(&reg->ictrl, ICR_EN_INT | ICR_EN_RISC);
-       RD_REG_WORD(&reg->ictrl);
-       spin_unlock_irqrestore(&ha->hardware_lock, flags);
- }
- static void
- qla2x00_disable_intrs(scsi_qla_host_t *ha)
- {
-       unsigned long flags = 0;
-       struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
-       spin_lock_irqsave(&ha->hardware_lock, flags);
-       ha->interrupts_on = 0;
-       /* disable risc and host interrupts */
-       WRT_REG_WORD(&reg->ictrl, 0);
-       RD_REG_WORD(&reg->ictrl);
-       spin_unlock_irqrestore(&ha->hardware_lock, flags);
- }
- static void
- qla24xx_enable_intrs(scsi_qla_host_t *ha)
- {
-       unsigned long flags = 0;
-       struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
-       spin_lock_irqsave(&ha->hardware_lock, flags);
-       ha->interrupts_on = 1;
-       WRT_REG_DWORD(&reg->ictrl, ICRX_EN_RISC_INT);
-       RD_REG_DWORD(&reg->ictrl);
-       spin_unlock_irqrestore(&ha->hardware_lock, flags);
- }
- static void
- qla24xx_disable_intrs(scsi_qla_host_t *ha)
- {
-       unsigned long flags = 0;
-       struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
-       spin_lock_irqsave(&ha->hardware_lock, flags);
-       ha->interrupts_on = 0;
-       WRT_REG_DWORD(&reg->ictrl, 0);
-       RD_REG_DWORD(&reg->ictrl);
-       spin_unlock_irqrestore(&ha->hardware_lock, flags);
- }
  static void
  qla2xxx_scan_start(struct Scsi_Host *shost)
  {
@@@ -1422,7 -1575,8 +1575,8 @@@ qla2x00_probe_one(struct pci_dev *pdev
        if (pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2422 ||
            pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2432 ||
            pdev->device == PCI_DEVICE_ID_QLOGIC_ISP5422 ||
-           pdev->device == PCI_DEVICE_ID_QLOGIC_ISP5432)
+           pdev->device == PCI_DEVICE_ID_QLOGIC_ISP5432 ||
+           pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2532)
                sht = &qla24xx_driver_template;
        host = scsi_host_alloc(sht, sizeof(scsi_qla_host_t));
        if (host == NULL) {
                ha->max_q_depth = ql2xmaxqdepth;
  
        /* Assign ISP specific operations. */
-       ha->isp_ops.pci_config          = qla2100_pci_config;
-       ha->isp_ops.reset_chip          = qla2x00_reset_chip;
-       ha->isp_ops.chip_diag           = qla2x00_chip_diag;
-       ha->isp_ops.config_rings        = qla2x00_config_rings;
-       ha->isp_ops.reset_adapter       = qla2x00_reset_adapter;
-       ha->isp_ops.nvram_config        = qla2x00_nvram_config;
-       ha->isp_ops.update_fw_options   = qla2x00_update_fw_options;
-       ha->isp_ops.load_risc           = qla2x00_load_risc;
-       ha->isp_ops.pci_info_str        = qla2x00_pci_info_str;
-       ha->isp_ops.fw_version_str      = qla2x00_fw_version_str;
-       ha->isp_ops.intr_handler        = qla2100_intr_handler;
-       ha->isp_ops.enable_intrs        = qla2x00_enable_intrs;
-       ha->isp_ops.disable_intrs       = qla2x00_disable_intrs;
-       ha->isp_ops.abort_command       = qla2x00_abort_command;
-       ha->isp_ops.abort_target        = qla2x00_abort_target;
-       ha->isp_ops.fabric_login        = qla2x00_login_fabric;
-       ha->isp_ops.fabric_logout       = qla2x00_fabric_logout;
-       ha->isp_ops.calc_req_entries    = qla2x00_calc_iocbs_32;
-       ha->isp_ops.build_iocbs         = qla2x00_build_scsi_iocbs_32;
-       ha->isp_ops.prep_ms_iocb        = qla2x00_prep_ms_iocb;
-       ha->isp_ops.prep_ms_fdmi_iocb   = qla2x00_prep_ms_fdmi_iocb;
-       ha->isp_ops.read_nvram          = qla2x00_read_nvram_data;
-       ha->isp_ops.write_nvram         = qla2x00_write_nvram_data;
-       ha->isp_ops.fw_dump             = qla2100_fw_dump;
-       ha->isp_ops.read_optrom         = qla2x00_read_optrom_data;
-       ha->isp_ops.write_optrom        = qla2x00_write_optrom_data;
-       ha->isp_ops.get_flash_version   = qla2x00_get_flash_version;
        if (IS_QLA2100(ha)) {
                host->max_id = MAX_TARGETS_2100;
                ha->mbx_count = MAILBOX_REGISTER_COUNT_2100;
                ha->last_loop_id = SNS_LAST_LOOP_ID_2100;
                host->sg_tablesize = 32;
                ha->gid_list_info_size = 4;
+               ha->isp_ops = &qla2100_isp_ops;
        } else if (IS_QLA2200(ha)) {
                host->max_id = MAX_TARGETS_2200;
                ha->mbx_count = MAILBOX_REGISTER_COUNT;
                ha->response_q_length = RESPONSE_ENTRY_CNT_2100;
                ha->last_loop_id = SNS_LAST_LOOP_ID_2100;
                ha->gid_list_info_size = 4;
+               ha->isp_ops = &qla2100_isp_ops;
        } else if (IS_QLA23XX(ha)) {
                host->max_id = MAX_TARGETS_2200;
                ha->mbx_count = MAILBOX_REGISTER_COUNT;
                ha->request_q_length = REQUEST_ENTRY_CNT_2200;
                ha->response_q_length = RESPONSE_ENTRY_CNT_2300;
                ha->last_loop_id = SNS_LAST_LOOP_ID_2300;
-               ha->isp_ops.pci_config = qla2300_pci_config;
-               ha->isp_ops.intr_handler = qla2300_intr_handler;
-               ha->isp_ops.fw_dump = qla2300_fw_dump;
-               ha->isp_ops.beacon_on = qla2x00_beacon_on;
-               ha->isp_ops.beacon_off = qla2x00_beacon_off;
-               ha->isp_ops.beacon_blink = qla2x00_beacon_blink;
                ha->gid_list_info_size = 6;
                if (IS_QLA2322(ha) || IS_QLA6322(ha))
                        ha->optrom_size = OPTROM_SIZE_2322;
+               ha->isp_ops = &qla2300_isp_ops;
        } else if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) {
                host->max_id = MAX_TARGETS_2200;
                ha->mbx_count = MAILBOX_REGISTER_COUNT;
                ha->last_loop_id = SNS_LAST_LOOP_ID_2300;
                ha->init_cb_size = sizeof(struct mid_init_cb_24xx);
                ha->mgmt_svr_loop_id = 10 + ha->vp_idx;
-               ha->isp_ops.pci_config = qla24xx_pci_config;
-               ha->isp_ops.reset_chip = qla24xx_reset_chip;
-               ha->isp_ops.chip_diag = qla24xx_chip_diag;
-               ha->isp_ops.config_rings = qla24xx_config_rings;
-               ha->isp_ops.reset_adapter = qla24xx_reset_adapter;
-               ha->isp_ops.nvram_config = qla24xx_nvram_config;
-               ha->isp_ops.update_fw_options = qla24xx_update_fw_options;
-               ha->isp_ops.load_risc = qla24xx_load_risc;
-               ha->isp_ops.pci_info_str = qla24xx_pci_info_str;
-               ha->isp_ops.fw_version_str = qla24xx_fw_version_str;
-               ha->isp_ops.intr_handler = qla24xx_intr_handler;
-               ha->isp_ops.enable_intrs = qla24xx_enable_intrs;
-               ha->isp_ops.disable_intrs = qla24xx_disable_intrs;
-               ha->isp_ops.abort_command = qla24xx_abort_command;
-               ha->isp_ops.abort_target = qla24xx_abort_target;
-               ha->isp_ops.fabric_login = qla24xx_login_fabric;
-               ha->isp_ops.fabric_logout = qla24xx_fabric_logout;
-               ha->isp_ops.prep_ms_iocb = qla24xx_prep_ms_iocb;
-               ha->isp_ops.prep_ms_fdmi_iocb = qla24xx_prep_ms_fdmi_iocb;
-               ha->isp_ops.read_nvram = qla24xx_read_nvram_data;
-               ha->isp_ops.write_nvram = qla24xx_write_nvram_data;
-               ha->isp_ops.fw_dump = qla24xx_fw_dump;
-               ha->isp_ops.read_optrom = qla24xx_read_optrom_data;
-               ha->isp_ops.write_optrom = qla24xx_write_optrom_data;
-               ha->isp_ops.beacon_on = qla24xx_beacon_on;
-               ha->isp_ops.beacon_off = qla24xx_beacon_off;
-               ha->isp_ops.beacon_blink = qla24xx_beacon_blink;
-               ha->isp_ops.get_flash_version = qla24xx_get_flash_version;
                ha->gid_list_info_size = 8;
                ha->optrom_size = OPTROM_SIZE_24XX;
+               ha->isp_ops = &qla24xx_isp_ops;
+       } else if (IS_QLA25XX(ha)) {
+               host->max_id = MAX_TARGETS_2200;
+               ha->mbx_count = MAILBOX_REGISTER_COUNT;
+               ha->request_q_length = REQUEST_ENTRY_CNT_24XX;
+               ha->response_q_length = RESPONSE_ENTRY_CNT_2300;
+               ha->last_loop_id = SNS_LAST_LOOP_ID_2300;
+               ha->init_cb_size = sizeof(struct mid_init_cb_24xx);
+               ha->mgmt_svr_loop_id = 10 + ha->vp_idx;
+               ha->gid_list_info_size = 8;
+               ha->optrom_size = OPTROM_SIZE_25XX;
+               ha->isp_ops = &qla25xx_isp_ops;
        }
        host->can_queue = ha->request_q_length + 128;
  
        DEBUG2(printk("DEBUG: detect hba %ld at address = %p\n",
            ha->host_no, ha));
  
-       ha->isp_ops.disable_intrs(ha);
+       ha->isp_ops->disable_intrs(ha);
  
        spin_lock_irqsave(&ha->hardware_lock, flags);
        reg = ha->iobase;
-       if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) {
+       if (IS_FWI2_CAPABLE(ha)) {
                WRT_REG_DWORD(&reg->isp24.hccr, HCCRX_CLR_HOST_INT);
                WRT_REG_DWORD(&reg->isp24.hccr, HCCRX_CLR_RISC_INT);
        } else {
        }
        spin_unlock_irqrestore(&ha->hardware_lock, flags);
  
-       ha->isp_ops.enable_intrs(ha);
+       ha->isp_ops->enable_intrs(ha);
  
        pci_set_drvdata(pdev, ha);
  
            "  ISP%04X: %s @ %s hdma%c, host#=%ld, fw=%s\n",
            qla2x00_version_str, ha->model_number,
            ha->model_desc ? ha->model_desc: "", pdev->device,
-           ha->isp_ops.pci_info_str(ha, pci_info), pci_name(pdev),
+           ha->isp_ops->pci_info_str(ha, pci_info), pci_name(pdev),
            ha->flags.enable_64bit_addressing ? '+': '-', ha->host_no,
-           ha->isp_ops.fw_version_str(ha, fw_str));
+           ha->isp_ops->fw_version_str(ha, fw_str));
  
        return 0;
  
@@@ -1747,7 -1855,7 +1855,7 @@@ qla2x00_free_device(scsi_qla_host_t *ha
  
        /* turn-off interrupts on the card */
        if (ha->interrupts_on)
-               ha->isp_ops.disable_intrs(ha);
+               ha->isp_ops->disable_intrs(ha);
  
        qla2x00_mem_free(ha);
  
@@@ -2025,7 -2133,7 +2133,7 @@@ qla2x00_mem_alloc(scsi_qla_host_t *ha
                        }
                        memset(ha->ct_sns, 0, sizeof(struct ct_sns_pkt));
  
-                       if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) {
+                       if (IS_FWI2_CAPABLE(ha)) {
                                /*
                                 * Get consistent memory allocated for SFP
                                 * block.
@@@ -2305,7 -2413,7 +2413,7 @@@ qla2x00_do_dpc(void *data
                                        if (fcport->flags & FCF_FABRIC_DEVICE) {
                                                if (fcport->flags &
                                                    FCF_TAPE_PRESENT)
-                                                       ha->isp_ops.fabric_logout(
+                                                       ha->isp_ops->fabric_logout(
                                                            ha, fcport->loop_id,
                                                            fcport->d_id.b.domain,
                                                            fcport->d_id.b.area,
                }
  
                if (!ha->interrupts_on)
-                       ha->isp_ops.enable_intrs(ha);
+                       ha->isp_ops->enable_intrs(ha);
  
                if (test_and_clear_bit(BEACON_BLINK_NEEDED, &ha->dpc_flags))
-                       ha->isp_ops.beacon_blink(ha);
+                       ha->isp_ops->beacon_blink(ha);
  
                qla2x00_do_dpc_all_vps(ha);
  
@@@ -2617,18 -2725,20 +2725,20 @@@ qla2x00_down_timeout(struct semaphore *
  
  /* Firmware interface routines. */
  
- #define FW_BLOBS      5
+ #define FW_BLOBS      6
  #define FW_ISP21XX    0
  #define FW_ISP22XX    1
  #define FW_ISP2300    2
  #define FW_ISP2322    3
  #define FW_ISP24XX    4
+ #define FW_ISP25XX    5
  
  #define FW_FILE_ISP21XX       "ql2100_fw.bin"
  #define FW_FILE_ISP22XX       "ql2200_fw.bin"
  #define FW_FILE_ISP2300       "ql2300_fw.bin"
  #define FW_FILE_ISP2322       "ql2322_fw.bin"
  #define FW_FILE_ISP24XX       "ql2400_fw.bin"
+ #define FW_FILE_ISP25XX       "ql2500_fw.bin"
  
  static DECLARE_MUTEX(qla_fw_lock);
  
@@@ -2638,6 -2748,7 +2748,7 @@@ static struct fw_blob qla_fw_blobs[FW_B
        { .name = FW_FILE_ISP2300, .segs = { 0x800, 0 }, },
        { .name = FW_FILE_ISP2322, .segs = { 0x800, 0x1c000, 0x1e000, 0 }, },
        { .name = FW_FILE_ISP24XX, },
+       { .name = FW_FILE_ISP25XX, },
  };
  
  struct fw_blob *
@@@ -2656,6 -2767,8 +2767,8 @@@ qla2x00_request_firmware(scsi_qla_host_
                blob = &qla_fw_blobs[FW_ISP2322];
        } else if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) {
                blob = &qla_fw_blobs[FW_ISP24XX];
+       } else if (IS_QLA25XX(ha)) {
+               blob = &qla_fw_blobs[FW_ISP25XX];
        }
  
        down(&qla_fw_lock);
@@@ -2699,6 -2812,7 +2812,7 @@@ static struct pci_device_id qla2xxx_pci
        { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2432) },
        { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP5422) },
        { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP5432) },
+       { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2532) },
        { 0 },
  };
  MODULE_DEVICE_TABLE(pci, qla2xxx_pci_tbl);
@@@ -2723,7 -2837,7 +2837,7 @@@ qla2x00_module_init(void
  
        /* Allocate cache for SRBs. */
        srb_cachep = kmem_cache_create("qla2xxx_srbs", sizeof(srb_t), 0,
 -          SLAB_HWCACHE_ALIGN, NULL, NULL);
 +          SLAB_HWCACHE_ALIGN, NULL);
        if (srb_cachep == NULL) {
                printk(KERN_ERR
                    "qla2xxx: Unable to allocate SRB cache...Failing load!\n");
diff --combined drivers/scsi/sim710.c
@@@ -100,7 -100,7 +100,7 @@@ sim710_probe_common(struct device *dev
  {
        struct Scsi_Host * host = NULL;
        struct NCR_700_Host_Parameters *hostdata =
 -              kmalloc(sizeof(struct NCR_700_Host_Parameters), GFP_KERNEL);
 +              kzalloc(sizeof(struct NCR_700_Host_Parameters), GFP_KERNEL);
  
        printk(KERN_NOTICE "sim710: %s\n", dev->bus_id);
        printk(KERN_NOTICE "sim710: irq = %d, clock = %d, base = 0x%lx, scsi_id = %d\n",
                printk(KERN_ERR "sim710: Failed to allocate host data\n");
                goto out;
        }
 -      memset(hostdata, 0, sizeof(struct NCR_700_Host_Parameters));
  
        if(request_region(base_addr, 64, "sim710") == NULL) {
                printk(KERN_ERR "sim710: Failed to reserve IO region 0x%lx\n",
                goto out_put_host;
        }
  
+       dev_set_drvdata(dev, host);
        scsi_scan_host(host);
  
        return 0;
  static __devexit int
  sim710_device_remove(struct device *dev)
  {
-       struct Scsi_Host *host = dev_to_shost(dev);
+       struct Scsi_Host *host = dev_get_drvdata(dev);
        struct NCR_700_Host_Parameters *hostdata =
                (struct NCR_700_Host_Parameters *)host->hostdata[0];
  
diff --combined include/linux/libata.h
@@@ -323,7 -323,6 +323,7 @@@ enum ata_completion_errors 
        AC_ERR_INVALID          = (1 << 7), /* invalid argument */
        AC_ERR_OTHER            = (1 << 8), /* unknown */
        AC_ERR_NODEV_HINT       = (1 << 9), /* polling device detection hint */
 +      AC_ERR_NCQ              = (1 << 10), /* marker for offending NCQ qc */
  };
  
  /* forward declarations */
@@@ -412,6 -411,7 +412,7 @@@ struct ata_queued_cmd 
        ata_qc_cb_t             complete_fn;
  
        void                    *private_data;
+       void                    *lldd_task;
  };
  
  struct ata_port_stats {
@@@ -531,7 -531,6 +532,7 @@@ struct ata_port 
        unsigned int            cbl;    /* cable type; ATA_CBL_xxx */
        unsigned int            hw_sata_spd_limit;
        unsigned int            sata_spd_limit; /* SATA PHY speed limit */
 +      unsigned int            sata_spd;       /* current SATA PHY speed */
  
        /* record runtime error info, protected by host lock */
        struct ata_eh_info      eh_info;
        pm_message_t            pm_mesg;
        int                     *pm_result;
  
 +      struct timer_list       fastdrain_timer;
 +      unsigned long           fastdrain_cnt;
 +
        void                    *private_data;
  
  #ifdef CONFIG_ATA_ACPI
@@@ -624,8 -620,9 +625,8 @@@ struct ata_port_operations 
        u8 (*irq_on) (struct ata_port *);
        u8 (*irq_ack) (struct ata_port *ap, unsigned int chk_drq);
  
 -      u32 (*scr_read) (struct ata_port *ap, unsigned int sc_reg);
 -      void (*scr_write) (struct ata_port *ap, unsigned int sc_reg,
 -                         u32 val);
 +      int (*scr_read) (struct ata_port *ap, unsigned int sc_reg, u32 *val);
 +      int (*scr_write) (struct ata_port *ap, unsigned int sc_reg, u32 val);
  
        int (*port_suspend) (struct ata_port *ap, pm_message_t mesg);
        int (*port_resume) (struct ata_port *ap);
@@@ -768,8 -765,7 +769,8 @@@ extern unsigned int ata_dev_try_classif
   */
  extern void ata_tf_load(struct ata_port *ap, const struct ata_taskfile *tf);
  extern void ata_tf_read(struct ata_port *ap, struct ata_taskfile *tf);
 -extern void ata_tf_to_fis(const struct ata_taskfile *tf, u8 *fis, u8 pmp);
 +extern void ata_tf_to_fis(const struct ata_taskfile *tf,
 +                        u8 pmp, int is_cmd, u8 *fis);
  extern void ata_tf_from_fis(const u8 *fis, struct ata_taskfile *tf);
  extern void ata_noop_dev_select (struct ata_port *ap, unsigned int device);
  extern void ata_std_dev_select (struct ata_port *ap, unsigned int device);
@@@ -914,21 -910,27 +915,21 @@@ extern void ata_do_eh(struct ata_port *
  /*
   * ata_eh_info helpers
   */
 -#define ata_ehi_push_desc(ehi, fmt, args...) do { \
 -      (ehi)->desc_len += scnprintf((ehi)->desc + (ehi)->desc_len, \
 -                                   ATA_EH_DESC_LEN - (ehi)->desc_len, \
 -                                   fmt , ##args); \
 -} while (0)
 -
 -#define ata_ehi_clear_desc(ehi) do { \
 -      (ehi)->desc[0] = '\0'; \
 -      (ehi)->desc_len = 0; \
 -} while (0)
 -
 -static inline void __ata_ehi_hotplugged(struct ata_eh_info *ehi)
 +extern void __ata_ehi_push_desc(struct ata_eh_info *ehi, const char *fmt, ...);
 +extern void ata_ehi_push_desc(struct ata_eh_info *ehi, const char *fmt, ...);
 +extern void ata_ehi_clear_desc(struct ata_eh_info *ehi);
 +
 +static inline void ata_ehi_schedule_probe(struct ata_eh_info *ehi)
  {
 -      ehi->flags |= ATA_EHI_HOTPLUGGED | ATA_EHI_RESUME_LINK;
 +      ehi->flags |= ATA_EHI_RESUME_LINK;
        ehi->action |= ATA_EH_SOFTRESET;
        ehi->probe_mask |= (1 << ATA_MAX_DEVICES) - 1;
  }
  
  static inline void ata_ehi_hotplugged(struct ata_eh_info *ehi)
  {
 -      __ata_ehi_hotplugged(ehi);
 +      ata_ehi_schedule_probe(ehi);
 +      ehi->flags |= ATA_EHI_HOTPLUGGED;
        ehi->err_mask |= AC_ERR_ATA_BUS;
  }
  
diff --combined include/linux/pci_ids.h
  
  #define PCI_VENDOR_ID_AMD             0x1022
  #define PCI_DEVICE_ID_AMD_K8_NB               0x1100
 +#define PCI_DEVICE_ID_AMD_K8_NB_ADDRMAP       0x1101
 +#define PCI_DEVICE_ID_AMD_K8_NB_MEMCTL        0x1102
  #define PCI_DEVICE_ID_AMD_K8_NB_MISC  0x1103
  #define PCI_DEVICE_ID_AMD_LANCE               0x2000
  #define PCI_DEVICE_ID_AMD_LANCE_HOME  0x2001
  
  #define PCI_VENDOR_ID_ARIMA           0x161f
  
+ #define PCI_VENDOR_ID_BROCADE         0x1657
  #define PCI_VENDOR_ID_SIBYTE          0x166d
  #define PCI_DEVICE_ID_BCM1250_PCI     0x0001
  #define PCI_DEVICE_ID_BCM1250_HT      0x0002
  #define PCI_DEVICE_ID_ALTIMA_AC9100   0x03ea
  #define PCI_DEVICE_ID_ALTIMA_AC1003   0x03eb
  
 +#define PCI_VENDOR_ID_LENOVO          0x17aa
 +
  #define PCI_VENDOR_ID_ARECA           0x17d3
  #define PCI_DEVICE_ID_ARECA_1110      0x1110
  #define PCI_DEVICE_ID_ARECA_1120      0x1120
  #define PCI_DEVICE_ID_INTEL_82915GM_IG        0x2592
  #define PCI_DEVICE_ID_INTEL_82945G_HB 0x2770
  #define PCI_DEVICE_ID_INTEL_82945G_IG 0x2772
 +#define PCI_DEVICE_ID_INTEL_3000_HB   0x2778
  #define PCI_DEVICE_ID_INTEL_82945GM_HB        0x27A0
  #define PCI_DEVICE_ID_INTEL_82945GM_IG        0x27A2
  #define PCI_DEVICE_ID_INTEL_ICH6_0    0x2640