]> git.karo-electronics.de Git - mv-sheeva.git/commitdiff
[SCSI] Merge up to linux-2.6 head
authorJames Bottomley <jejb@mulgrave.il.steeleye.com>
Thu, 31 May 2007 04:57:05 +0000 (23:57 -0500)
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>
Thu, 31 May 2007 04:57:05 +0000 (23:57 -0500)
Conflicts:

drivers/scsi/jazz_esp.c

Same changes made by both SCSI and SPARC trees: problem with UTF-8
conversion in the copyright.

Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
1  2 
drivers/ieee1394/sbp2.c
drivers/message/fusion/mptscsih.c
drivers/scsi/Kconfig
drivers/scsi/Makefile
drivers/scsi/aacraid/aachba.c
drivers/scsi/aacraid/aacraid.h
drivers/scsi/ipr.c
drivers/scsi/sd.c
drivers/scsi/stex.c

diff --combined drivers/ieee1394/sbp2.c
index d0db6f8b520627ac824bf57d5ec9aa06d72a5f0c,875eadd5e8f551bcc5c261d892a1d4c3d6b24f49..ce86ff226a283c2e185c7bcbe93c6261c906914c
@@@ -70,6 -70,7 +70,7 @@@
  #include <linux/stringify.h>
  #include <linux/types.h>
  #include <linux/wait.h>
+ #include <linux/workqueue.h>
  
  #include <asm/byteorder.h>
  #include <asm/errno.h>
@@@ -1488,6 -1489,69 +1489,6 @@@ static void sbp2_prep_command_orb_sg(st
        }
  }
  
 -static void sbp2_prep_command_orb_no_sg(struct sbp2_command_orb *orb,
 -                                      struct sbp2_fwhost_info *hi,
 -                                      struct sbp2_command_info *cmd,
 -                                      struct scatterlist *sgpnt,
 -                                      u32 orb_direction,
 -                                      unsigned int scsi_request_bufflen,
 -                                      void *scsi_request_buffer,
 -                                      enum dma_data_direction dma_dir)
 -{
 -      cmd->dma_dir = dma_dir;
 -      cmd->dma_size = scsi_request_bufflen;
 -      cmd->dma_type = CMD_DMA_SINGLE;
 -      cmd->cmd_dma = dma_map_single(hi->host->device.parent,
 -                                    scsi_request_buffer,
 -                                    cmd->dma_size, cmd->dma_dir);
 -      orb->data_descriptor_hi = ORB_SET_NODE_ID(hi->host->node_id);
 -      orb->misc |= ORB_SET_DIRECTION(orb_direction);
 -
 -      /* handle case where we get a command w/o s/g enabled
 -       * (but check for transfers larger than 64K) */
 -      if (scsi_request_bufflen <= SBP2_MAX_SG_ELEMENT_LENGTH) {
 -
 -              orb->data_descriptor_lo = cmd->cmd_dma;
 -              orb->misc |= ORB_SET_DATA_SIZE(scsi_request_bufflen);
 -
 -      } else {
 -              /* The buffer is too large. Turn this into page tables. */
 -
 -              struct sbp2_unrestricted_page_table *sg_element =
 -                                              &cmd->scatter_gather_element[0];
 -              u32 sg_count, sg_len;
 -              dma_addr_t sg_addr;
 -
 -              orb->data_descriptor_lo = cmd->sge_dma;
 -              orb->misc |= ORB_SET_PAGE_TABLE_PRESENT(0x1);
 -
 -              /* fill out our SBP-2 page tables; split up the large buffer */
 -              sg_count = 0;
 -              sg_len = scsi_request_bufflen;
 -              sg_addr = cmd->cmd_dma;
 -              while (sg_len) {
 -                      sg_element[sg_count].segment_base_lo = sg_addr;
 -                      if (sg_len > SBP2_MAX_SG_ELEMENT_LENGTH) {
 -                              sg_element[sg_count].length_segment_base_hi =
 -                                      PAGE_TABLE_SET_SEGMENT_LENGTH(SBP2_MAX_SG_ELEMENT_LENGTH);
 -                              sg_addr += SBP2_MAX_SG_ELEMENT_LENGTH;
 -                              sg_len -= SBP2_MAX_SG_ELEMENT_LENGTH;
 -                      } else {
 -                              sg_element[sg_count].length_segment_base_hi =
 -                                      PAGE_TABLE_SET_SEGMENT_LENGTH(sg_len);
 -                              sg_len = 0;
 -                      }
 -                      sg_count++;
 -              }
 -
 -              orb->misc |= ORB_SET_DATA_SIZE(sg_count);
 -
 -              sbp2util_cpu_to_be32_buffer(sg_element,
 -                              (sizeof(struct sbp2_unrestricted_page_table)) *
 -                              sg_count);
 -      }
 -}
 -
  static void sbp2_create_command_orb(struct sbp2_lu *lu,
                                    struct sbp2_command_info *cmd,
                                    unchar *scsi_cmd,
                orb->data_descriptor_hi = 0x0;
                orb->data_descriptor_lo = 0x0;
                orb->misc |= ORB_SET_DIRECTION(1);
 -      } else if (scsi_use_sg)
 +      } else
                sbp2_prep_command_orb_sg(orb, hi, cmd, scsi_use_sg, sgpnt,
                                         orb_direction, dma_dir);
 -      else
 -              sbp2_prep_command_orb_no_sg(orb, hi, cmd, sgpnt, orb_direction,
 -                                          scsi_request_bufflen,
 -                                          scsi_request_buffer, dma_dir);
  
        sbp2util_cpu_to_be32_buffer(orb, sizeof(*orb));
  
@@@ -1622,15 -1690,15 +1623,15 @@@ static int sbp2_send_command(struct sbp
                             void (*done)(struct scsi_cmnd *))
  {
        unchar *scsi_cmd = (unchar *)SCpnt->cmnd;
 -      unsigned int request_bufflen = SCpnt->request_bufflen;
 +      unsigned int request_bufflen = scsi_bufflen(SCpnt);
        struct sbp2_command_info *cmd;
  
        cmd = sbp2util_allocate_command_orb(lu, SCpnt, done);
        if (!cmd)
                return -EIO;
  
 -      sbp2_create_command_orb(lu, cmd, scsi_cmd, SCpnt->use_sg,
 -                              request_bufflen, SCpnt->request_buffer,
 +      sbp2_create_command_orb(lu, cmd, scsi_cmd, scsi_sg_count(SCpnt),
 +                              request_bufflen, scsi_sglist(SCpnt),
                                SCpnt->sc_data_direction);
        sbp2_link_orb_command(lu, cmd);
  
index 561074a04b03ce83b381c68201986b78763e46ea,3bd94f11e7d6ef417244f48036e24a9b696aebc0..bc740a6dd93c612e6d41e09a2be7670331013029
@@@ -260,13 -260,30 +260,13 @@@ mptscsih_AddSGE(MPT_ADAPTER *ioc, struc
        /* Map the data portion, if any.
         * sges_left  = 0 if no data transfer.
         */
 -      if ( (sges_left = SCpnt->use_sg) ) {
 -              sges_left = pci_map_sg(ioc->pcidev,
 -                             (struct scatterlist *) SCpnt->request_buffer,
 -                             SCpnt->use_sg,
 -                             SCpnt->sc_data_direction);
 -              if (sges_left == 0)
 -                      return FAILED;
 -      } else if (SCpnt->request_bufflen) {
 -              SCpnt->SCp.dma_handle = pci_map_single(ioc->pcidev,
 -                                    SCpnt->request_buffer,
 -                                    SCpnt->request_bufflen,
 -                                    SCpnt->sc_data_direction);
 -              dsgprintk((MYIOC_s_INFO_FMT "SG: non-SG for %p, len=%d\n",
 -                              ioc->name, SCpnt, SCpnt->request_bufflen));
 -              mptscsih_add_sge((char *) &pReq->SGL,
 -                      0xD1000000|MPT_SGE_FLAGS_ADDRESSING|sgdir|SCpnt->request_bufflen,
 -                      SCpnt->SCp.dma_handle);
 -
 -              return SUCCESS;
 -      }
 +      sges_left = scsi_dma_map(SCpnt);
 +      if (sges_left < 0)
 +              return FAILED;
  
        /* Handle the SG case.
         */
 -      sg = (struct scatterlist *) SCpnt->request_buffer;
 +      sg = scsi_sglist(SCpnt);
        sg_done  = 0;
        sgeOffset = sizeof(SCSIIORequest_t) - sizeof(SGE_IO_UNION);
        chainSge = NULL;
@@@ -645,7 -662,7 +645,7 @@@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_
                scsi_state = pScsiReply->SCSIState;
                scsi_status = pScsiReply->SCSIStatus;
                xfer_cnt = le32_to_cpu(pScsiReply->TransferCount);
 -              sc->resid = sc->request_bufflen - xfer_cnt;
 +              scsi_set_resid(sc, scsi_bufflen(sc) - xfer_cnt);
                log_info = le32_to_cpu(pScsiReply->IOCLogInfo);
  
                /*
                        break;
  
                case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH:      /* 0x0049 */
 -                      sc->resid = sc->request_bufflen - xfer_cnt;
 +                      scsi_set_resid(sc, scsi_bufflen(sc) - xfer_cnt);
                        if((xfer_cnt==0)||(sc->underflow > xfer_cnt))
                                sc->result=DID_SOFT_ERROR << 16;
                        else /* Sufficient data transfer occurred */
                        break;
  
                case MPI_IOCSTATUS_SCSI_DATA_OVERRUN:           /* 0x0044 */
 -                      sc->resid=0;
 +                      scsi_set_resid(sc, 0);
                case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR:        /* 0x0040 */
                case MPI_IOCSTATUS_SUCCESS:                     /* 0x0000 */
                        sc->result = (DID_OK << 16) | scsi_status;
                            scsi_state, scsi_status, log_info));
  
                        dreplyprintk(("%s: [%d:%d:%d:%d] resid=%d "
 -                          "bufflen=%d xfer_cnt=%d\n", __FUNCTION__,
 -                          sc->device->host->host_no, sc->device->channel, sc->device->id,
 -                          sc->device->lun, sc->resid, sc->request_bufflen,
 -                          xfer_cnt));
 +                                    "bufflen=%d xfer_cnt=%d\n", __FUNCTION__,
 +                                    sc->device->host->host_no,
 +                                    sc->device->channel, sc->device->id,
 +                                    sc->device->lun, scsi_get_resid(sc),
 +                                    scsi_bufflen(sc), xfer_cnt));
                }
  #endif
  
        } /* end of address reply case */
  
        /* Unmap the DMA buffers, if any. */
 -      if (sc->use_sg) {
 -              pci_unmap_sg(ioc->pcidev, (struct scatterlist *) sc->request_buffer,
 -                          sc->use_sg, sc->sc_data_direction);
 -      } else if (sc->request_bufflen) {
 -              pci_unmap_single(ioc->pcidev, sc->SCp.dma_handle,
 -                              sc->request_bufflen, sc->sc_data_direction);
 -      }
 +      scsi_dma_unmap(sc);
  
        sc->scsi_done(sc);              /* Issue the command callback */
  
@@@ -948,8 -970,17 +948,8 @@@ mptscsih_flush_running_cmds(MPT_SCSI_HO
                        /* Set status, free OS resources (SG DMA buffers)
                         * Do OS callback
                         */
 -                      if (SCpnt->use_sg) {
 -                              pci_unmap_sg(ioc->pcidev,
 -                                      (struct scatterlist *) SCpnt->request_buffer,
 -                                      SCpnt->use_sg,
 -                                      SCpnt->sc_data_direction);
 -                      } else if (SCpnt->request_bufflen) {
 -                              pci_unmap_single(ioc->pcidev,
 -                                      SCpnt->SCp.dma_handle,
 -                                      SCpnt->request_bufflen,
 -                                      SCpnt->sc_data_direction);
 -                      }
 +                      scsi_dma_unmap(SCpnt);
 +
                        SCpnt->result = DID_RESET << 16;
                        SCpnt->host_scribble = NULL;
  
@@@ -1008,8 -1039,17 +1008,8 @@@ mptscsih_search_running_cmds(MPT_SCSI_H
                        mpt_free_msg_frame(hd->ioc, (MPT_FRAME_HDR *)mf);
                        if ((unsigned char *)mf != sc->host_scribble)
                                continue;
 -                      if (sc->use_sg) {
 -                              pci_unmap_sg(hd->ioc->pcidev,
 -                              (struct scatterlist *) sc->request_buffer,
 -                                      sc->use_sg,
 -                                      sc->sc_data_direction);
 -                      } else if (sc->request_bufflen) {
 -                              pci_unmap_single(hd->ioc->pcidev,
 -                                      sc->SCp.dma_handle,
 -                                      sc->request_bufflen,
 -                                      sc->sc_data_direction);
 -                      }
 +                      scsi_dma_unmap(sc);
 +
                        sc->host_scribble = NULL;
                        sc->result = DID_NO_CONNECT << 16;
                        sc->scsi_done(sc);
@@@ -1340,10 -1380,10 +1340,10 @@@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, 
         *    will be no data transfer!  GRRRRR...
         */
        if (SCpnt->sc_data_direction == DMA_FROM_DEVICE) {
 -              datalen = SCpnt->request_bufflen;
 +              datalen = scsi_bufflen(SCpnt);
                scsidir = MPI_SCSIIO_CONTROL_READ;      /* DATA IN  (host<--ioc<--dev) */
        } else if (SCpnt->sc_data_direction == DMA_TO_DEVICE) {
 -              datalen = SCpnt->request_bufflen;
 +              datalen = scsi_bufflen(SCpnt);
                scsidir = MPI_SCSIIO_CONTROL_WRITE;     /* DATA OUT (host-->ioc-->dev) */
        } else {
                datalen = 0;
@@@ -2423,11 -2463,11 +2423,11 @@@ mptscsih_copy_sense_data(struct scsi_cm
                                ioc->events[idx].event = MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE;
                                ioc->events[idx].eventContext = ioc->eventContext;
  
-                               ioc->events[idx].data[0] = (pReq->LUN[1] << 24) ||
-                                       (MPI_EVENT_SCSI_DEV_STAT_RC_SMART_DATA << 16) ||
-                                       (sc->device->channel << 8) || sc->device->id;
+                               ioc->events[idx].data[0] = (pReq->LUN[1] << 24) |
+                                       (MPI_EVENT_SCSI_DEV_STAT_RC_SMART_DATA << 16) |
+                                       (sc->device->channel << 8) | sc->device->id;
  
-                               ioc->events[idx].data[1] = (sense_data[13] << 8) || sense_data[12];
+                               ioc->events[idx].data[1] = (sense_data[13] << 8) | sense_data[12];
  
                                ioc->eventContext++;
                                if (hd->ioc->pcidev->vendor ==
diff --combined drivers/scsi/Kconfig
index d6510ef03035fbbd3227bab7abab1f1dc0951f42,572034ceb1434ebfe09e7281aeb020ca9d4e333c..aac9cd9a172f0c5f57eb21fede3e95596cd28d8f
@@@ -738,7 -738,7 +738,7 @@@ config SCSI_GENERIC_NCR53C40
  
  config SCSI_IBMMCA
        tristate "IBMMCA SCSI support"
 -      depends on MCA_LEGACY && SCSI
 +      depends on MCA && SCSI
        ---help---
          This is support for the IBM SCSI adapter found in many of the PS/2
          series computers.  These machines have an MCA bus, so you need to
@@@ -1753,23 -1753,9 +1753,9 @@@ config SUN3X_ES
          The ESP was an on-board SCSI controller used on Sun 3/80
          machines.  Say Y here to compile in support for it.
  
- config SCSI_ESP_CORE
-       tristate "ESP Scsi Driver Core"
-       depends on SCSI
-       select SCSI_SPI_ATTRS
-       help
-         This is a core driver for NCR53c9x based scsi chipsets,
-         also known as "ESP" for Emulex Scsi Processor or
-         Enhanced Scsi Processor.  This driver does not exist by
-         itself, there are front-end drivers which, when enabled,
-         select and enable this driver.  One example is SCSI_SUNESP.
-         These front-end drivers provide probing, DMA, and register
-         access support for the core driver.
  config SCSI_SUNESP
        tristate "Sparc ESP Scsi Driver"
        depends on SBUS && SCSI
-       select SCSI_ESP_CORE
        help
          This is the driver for the Sun ESP SCSI host adapter. The ESP
          chipset is present in most SPARC SBUS-based computers.
diff --combined drivers/scsi/Makefile
index 51cba91cd228e365696d9fe1262c76950e224d51,b1b632791580517d215d3280e2f64b3dd5ed7889..cba39679f947943b5cb88acada80a9135c0110b6
@@@ -37,6 -37,7 +37,6 @@@ obj-$(CONFIG_SCSI_SAS_LIBSAS) += libsas
  
  obj-$(CONFIG_ISCSI_TCP)       += libiscsi.o   iscsi_tcp.o
  obj-$(CONFIG_INFINIBAND_ISER)         += libiscsi.o
 -obj-$(CONFIG_SCSI_AMIGA7XX)   += amiga7xx.o   53c7xx.o
  obj-$(CONFIG_A3000_SCSI)      += a3000.o      wd33c93.o
  obj-$(CONFIG_A2091_SCSI)      += a2091.o      wd33c93.o
  obj-$(CONFIG_GVP11_SCSI)      += gvp11.o      wd33c93.o
@@@ -52,6 -53,8 +52,6 @@@ obj-$(CONFIG_ATARI_SCSI)      += atari_scsi.
  obj-$(CONFIG_MAC_SCSI)                += mac_scsi.o
  obj-$(CONFIG_SCSI_MAC_ESP)    += mac_esp.o    NCR53C9x.o
  obj-$(CONFIG_SUN3_SCSI)               += sun3_scsi.o  sun3_scsi_vme.o
 -obj-$(CONFIG_MVME16x_SCSI)    += mvme16x.o    53c7xx.o
 -obj-$(CONFIG_BVME6000_SCSI)   += bvme6000.o   53c7xx.o
  obj-$(CONFIG_SCSI_SIM710)     += 53c700.o     sim710.o
  obj-$(CONFIG_SCSI_ADVANSYS)   += advansys.o
  obj-$(CONFIG_SCSI_PSI240I)    += psi240i.o
@@@ -103,8 -106,7 +103,7 @@@ obj-$(CONFIG_MEGARAID_LEGACY)      += megara
  obj-$(CONFIG_MEGARAID_NEWGEN) += megaraid/
  obj-$(CONFIG_MEGARAID_SAS)    += megaraid/
  obj-$(CONFIG_SCSI_ACARD)      += atp870u.o
- obj-$(CONFIG_SCSI_ESP_CORE)   += esp_scsi.o
- obj-$(CONFIG_SCSI_SUNESP)     += sun_esp.o
+ obj-$(CONFIG_SCSI_SUNESP)     += esp_scsi.o   sun_esp.o
  obj-$(CONFIG_SCSI_GDTH)               += gdth.o
  obj-$(CONFIG_SCSI_INITIO)     += initio.o
  obj-$(CONFIG_SCSI_INIA100)    += a100u2w.o
@@@ -166,8 -168,10 +165,8 @@@ NCR_Q720_mod-objs := NCR_Q720.o ncr53c8
  oktagon_esp_mod-objs  := oktagon_esp.o oktagon_io.o
  
  # Files generated that shall be removed upon make clean
 -clean-files :=        53c7xx_d.h 53c700_d.h   \
 -              53c7xx_u.h 53c700_u.h
 +clean-files :=        53c700_d.h 53c700_u.h
  
 -$(obj)/53c7xx.o:   $(obj)/53c7xx_d.h $(obj)/53c7xx_u.h
  $(obj)/53c700.o $(MODVERDIR)/$(obj)/53c700.ver: $(obj)/53c700_d.h
  
  # If you want to play with the firmware, uncomment
  
  ifdef GENERATE_FIRMWARE
  
 -$(obj)/53c7xx_d.h: $(src)/53c7xx.scr $(src)/script_asm.pl
 -      $(CPP) -traditional -DCHIP=710 - < $< | grep -v '^#' | $(PERL) -s $(src)/script_asm.pl -ncr7x0_family $@ $(@:_d.h=_u.h)
 -
 -$(obj)/53c7xx_u.h: $(obj)/53c7xx_d.h
 -
  $(obj)/53c700_d.h: $(src)/53c700.scr $(src)/script_asm.pl
        $(PERL) -s $(src)/script_asm.pl -ncr7x0_family $@ $(@:_d.h=_u.h) < $<
  
index a333e62fc487e959485c4a2b90d9418650ef96a0,8dcfe4ec35c224d2b296df65455817d608d3b9e8..47014beef96e131232ec8ee55389b2bdd7b563af
@@@ -146,7 -146,7 +146,7 @@@ static char *aac_get_status_string(u32 
  static int nondasd = -1;
  static int dacmode = -1;
  
static int commit = -1;
int aac_commit = -1;
  int startup_timeout = 180;
  int aif_timeout = 120;
  
@@@ -154,7 -154,7 +154,7 @@@ module_param(nondasd, int, S_IRUGO|S_IW
  MODULE_PARM_DESC(nondasd, "Control scanning of hba for nondasd devices. 0=off, 1=on");
  module_param(dacmode, int, S_IRUGO|S_IWUSR);
  MODULE_PARM_DESC(dacmode, "Control whether dma addressing is using 64 bit DAC. 0=off, 1=on");
- module_param(commit, int, S_IRUGO|S_IWUSR);
+ module_param_named(commit, aac_commit, int, S_IRUGO|S_IWUSR);
  MODULE_PARM_DESC(commit, "Control whether a COMMIT_CONFIG is issued to the adapter for foreign arrays.\nThis is typically needed in systems that do not have a BIOS. 0=off, 1=on");
  module_param(startup_timeout, int, S_IRUGO|S_IWUSR);
  MODULE_PARM_DESC(startup_timeout, "The duration of time in seconds to wait for adapter to have it's kernel up and\nrunning. This is typically adjusted for large systems that do not have a BIOS.");
@@@ -173,6 -173,9 +173,9 @@@ int expose_physicals = -1
  module_param(expose_physicals, int, S_IRUGO|S_IWUSR);
  MODULE_PARM_DESC(expose_physicals, "Expose physical components of the arrays. -1=protect 0=off, 1=on");
  
+ int aac_reset_devices = 0;
+ module_param_named(reset_devices, aac_reset_devices, int, S_IRUGO|S_IWUSR);
+ MODULE_PARM_DESC(reset_devices, "Force an adapter reset at initialization.");
  
  static inline int aac_valid_context(struct scsi_cmnd *scsicmd,
                struct fib *fibptr) {
@@@ -246,7 -249,7 +249,7 @@@ int aac_get_config_status(struct aac_de
        aac_fib_complete(fibptr);
        /* Send a CT_COMMIT_CONFIG to enable discovery of devices */
        if (status >= 0) {
-               if ((commit == 1) || commit_flag) {
+               if ((aac_commit == 1) || commit_flag) {
                        struct aac_commit_config * dinfo;
                        aac_fib_init(fibptr);
                        dinfo = (struct aac_commit_config *) fib_data(fibptr);
                                    1, 1,
                                    NULL, NULL);
                        aac_fib_complete(fibptr);
-               } else if (commit == 0) {
+               } else if (aac_commit == 0) {
                        printk(KERN_WARNING
                          "aac_get_config_status: Foreign device configurations are being ignored\n");
                }
@@@ -340,7 -343,7 +343,7 @@@ int aac_get_containers(struct aac_dev *
  static void aac_internal_transfer(struct scsi_cmnd *scsicmd, void *data, unsigned int offset, unsigned int len)
  {
        void *buf;
-       unsigned int transfer_len;
+       int transfer_len;
        struct scatterlist *sg = scsicmd->request_buffer;
  
        if (scsicmd->use_sg) {
                transfer_len = min(scsicmd->request_bufflen, len + offset);
        }
        transfer_len -= offset;
-       if (buf && transfer_len)
+       if (buf && transfer_len > 0)
                memcpy(buf + offset, data, transfer_len);
  
        if (scsicmd->use_sg) 
@@@ -822,7 -825,7 +825,7 @@@ static int aac_read_raw_io(struct fib 
        readcmd->block[1] = cpu_to_le32((u32)((lba&0xffffffff00000000LL)>>32));
        readcmd->count = cpu_to_le32(count<<9);
        readcmd->cid = cpu_to_le16(scmd_id(cmd));
 -      readcmd->flags = cpu_to_le16(1);
 +      readcmd->flags = cpu_to_le16(IO_TYPE_READ);
        readcmd->bpTotal = 0;
        readcmd->bpComplete = 0;
  
@@@ -901,7 -904,7 +904,7 @@@ static int aac_read_block(struct fib * 
                          (void *) cmd);
  }
  
 -static int aac_write_raw_io(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u32 count)
 +static int aac_write_raw_io(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u32 count, int fua)
  {
        u16 fibsize;
        struct aac_raw_io *writecmd;
        writecmd->block[1] = cpu_to_le32((u32)((lba&0xffffffff00000000LL)>>32));
        writecmd->count = cpu_to_le32(count<<9);
        writecmd->cid = cpu_to_le16(scmd_id(cmd));
 -      writecmd->flags = 0;
 +      writecmd->flags = fua ?
 +              cpu_to_le16(IO_TYPE_WRITE|IO_SUREWRITE) :
 +              cpu_to_le16(IO_TYPE_WRITE);
        writecmd->bpTotal = 0;
        writecmd->bpComplete = 0;
  
                          (void *) cmd);
  }
  
 -static int aac_write_block64(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u32 count)
 +static int aac_write_block64(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u32 count, int fua)
  {
        u16 fibsize;
        struct aac_write64 *writecmd;
                          (void *) cmd);
  }
  
 -static int aac_write_block(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u32 count)
 +static int aac_write_block(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u32 count, int fua)
  {
        u16 fibsize;
        struct aac_write *writecmd;
@@@ -1497,7 -1498,6 +1500,7 @@@ static int aac_write(struct scsi_cmnd 
  {
        u64 lba;
        u32 count;
 +      int fua;
        int status;
        struct aac_dev *dev;
        struct fib * cmd_fibcontext;
                count = scsicmd->cmnd[4];
                if (count == 0)
                        count = 256;
 +              fua = 0;
        } else if (scsicmd->cmnd[0] == WRITE_16) { /* 16 byte command */
                dprintk((KERN_DEBUG "aachba: received a write(16) command on id %d.\n", scmd_id(scsicmd)));
  
                        (scsicmd->cmnd[8] << 8) | scsicmd->cmnd[9];
                count = (scsicmd->cmnd[10] << 24) | (scsicmd->cmnd[11] << 16) |
                        (scsicmd->cmnd[12] << 8) | scsicmd->cmnd[13];
 +              fua = scsicmd->cmnd[1] & 0x8;
        } else if (scsicmd->cmnd[0] == WRITE_12) { /* 12 byte command */
                dprintk((KERN_DEBUG "aachba: received a write(12) command on id %d.\n", scmd_id(scsicmd)));
  
                    | (scsicmd->cmnd[4] << 8) | scsicmd->cmnd[5];
                count = (scsicmd->cmnd[6] << 24) | (scsicmd->cmnd[7] << 16)
                      | (scsicmd->cmnd[8] << 8) | scsicmd->cmnd[9];
 +              fua = scsicmd->cmnd[1] & 0x8;
        } else {
                dprintk((KERN_DEBUG "aachba: received a write(10) command on id %d.\n", scmd_id(scsicmd)));
                lba = ((u64)scsicmd->cmnd[2] << 24) | (scsicmd->cmnd[3] << 16) | (scsicmd->cmnd[4] << 8) | scsicmd->cmnd[5];
                count = (scsicmd->cmnd[7] << 8) | scsicmd->cmnd[8];
 +              fua = scsicmd->cmnd[1] & 0x8;
        }
        dprintk((KERN_DEBUG "aac_write[cpu %d]: lba = %llu, t = %ld.\n",
          smp_processor_id(), (unsigned long long)lba, jiffies));
                return 0;
        }
  
 -      status = aac_adapter_write(cmd_fibcontext, scsicmd, lba, count);
 +      status = aac_adapter_write(cmd_fibcontext, scsicmd, lba, count, fua);
  
        /*
         *      Check that the command queued to the controller
@@@ -1890,29 -1886,15 +1893,29 @@@ int aac_scsi_cmd(struct scsi_cmnd * scs
  
        case MODE_SENSE:
        {
 -              char mode_buf[4];
 +              char mode_buf[7];
 +              int mode_buf_length = 4;
  
                dprintk((KERN_DEBUG "MODE SENSE command.\n"));
                mode_buf[0] = 3;        /* Mode data length */
                mode_buf[1] = 0;        /* Medium type - default */
 -              mode_buf[2] = 0;        /* Device-specific param, bit 8: 0/1 = write enabled/protected */
 +              mode_buf[2] = 0;        /* Device-specific param,
 +                                         bit 8: 0/1 = write enabled/protected
 +                                         bit 4: 0/1 = FUA enabled */
 +              if (dev->raw_io_interface)
 +                      mode_buf[2] = 0x10;
                mode_buf[3] = 0;        /* Block descriptor length */
 -
 -              aac_internal_transfer(scsicmd, mode_buf, 0, sizeof(mode_buf));
 +              if (((scsicmd->cmnd[2] & 0x3f) == 8) ||
 +                ((scsicmd->cmnd[2] & 0x3f) == 0x3f)) {
 +                      mode_buf[0] = 6;
 +                      mode_buf[4] = 8;
 +                      mode_buf[5] = 1;
 +                      mode_buf[6] = 0x04; /* WCE */
 +                      mode_buf_length = 7;
 +                      if (mode_buf_length > scsicmd->cmnd[4])
 +                              mode_buf_length = scsicmd->cmnd[4];
 +              }
 +              aac_internal_transfer(scsicmd, mode_buf, 0, mode_buf_length);
                scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
                scsicmd->scsi_done(scsicmd);
  
        }
        case MODE_SENSE_10:
        {
 -              char mode_buf[8];
 +              char mode_buf[11];
 +              int mode_buf_length = 8;
  
                dprintk((KERN_DEBUG "MODE SENSE 10 byte command.\n"));
                mode_buf[0] = 0;        /* Mode data length (MSB) */
                mode_buf[1] = 6;        /* Mode data length (LSB) */
                mode_buf[2] = 0;        /* Medium type - default */
 -              mode_buf[3] = 0;        /* Device-specific param, bit 8: 0/1 = write enabled/protected */
 +              mode_buf[3] = 0;        /* Device-specific param,
 +                                         bit 8: 0/1 = write enabled/protected
 +                                         bit 4: 0/1 = FUA enabled */
 +              if (dev->raw_io_interface)
 +                      mode_buf[3] = 0x10;
                mode_buf[4] = 0;        /* reserved */
                mode_buf[5] = 0;        /* reserved */
                mode_buf[6] = 0;        /* Block descriptor length (MSB) */
                mode_buf[7] = 0;        /* Block descriptor length (LSB) */
 -              aac_internal_transfer(scsicmd, mode_buf, 0, sizeof(mode_buf));
 +              if (((scsicmd->cmnd[2] & 0x3f) == 8) ||
 +                ((scsicmd->cmnd[2] & 0x3f) == 0x3f)) {
 +                      mode_buf[1] = 9;
 +                      mode_buf[8] = 8;
 +                      mode_buf[9] = 1;
 +                      mode_buf[10] = 0x04; /* WCE */
 +                      mode_buf_length = 11;
 +                      if (mode_buf_length > scsicmd->cmnd[8])
 +                              mode_buf_length = scsicmd->cmnd[8];
 +              }
 +              aac_internal_transfer(scsicmd, mode_buf, 0, mode_buf_length);
  
                scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
                scsicmd->scsi_done(scsicmd);
index a3138ee910501f7f71a679d31a373eaabf4e95ab,c81edf36913f89025c2f6095589a3040aaffeea9..fdbedb17d03bf4adf1c2066621a402f2a61f7c1f
@@@ -464,12 -464,12 +464,12 @@@ struct adapter_op
        int  (*adapter_restart)(struct aac_dev *dev, int bled);
        /* Transport operations */
        int  (*adapter_ioremap)(struct aac_dev * dev, u32 size);
 -      irqreturn_t (*adapter_intr)(int irq, void *dev_id);
 +      irq_handler_t adapter_intr;
        /* Packet operations */
        int  (*adapter_deliver)(struct fib * fib);
        int  (*adapter_bounds)(struct aac_dev * dev, struct scsi_cmnd * cmd, u64 lba);
        int  (*adapter_read)(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u32 count);
 -      int  (*adapter_write)(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u32 count);
 +      int  (*adapter_write)(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u32 count, int fua);
        int  (*adapter_scsi)(struct fib * fib, struct scsi_cmnd * cmd);
        /* Administrative operations */
        int  (*adapter_comm)(struct aac_dev * dev, int comm);
@@@ -1054,8 -1054,8 +1054,8 @@@ struct aac_de
  #define aac_adapter_read(fib,cmd,lba,count) \
        ((fib)->dev)->a_ops.adapter_read(fib,cmd,lba,count)
  
 -#define aac_adapter_write(fib,cmd,lba,count) \
 -      ((fib)->dev)->a_ops.adapter_write(fib,cmd,lba,count)
 +#define aac_adapter_write(fib,cmd,lba,count,fua) \
 +      ((fib)->dev)->a_ops.adapter_write(fib,cmd,lba,count,fua)
  
  #define aac_adapter_scsi(fib,cmd) \
        ((fib)->dev)->a_ops.adapter_scsi(fib,cmd)
@@@ -1213,9 -1213,6 +1213,9 @@@ struct aac_write6
        __le32          block;
        __le16          pad;
        __le16          flags;
 +#define       IO_TYPE_WRITE 0x00000000
 +#define       IO_TYPE_READ  0x00000001
 +#define       IO_SUREWRITE  0x00000008
        struct sgmap64  sg;     // Must be last in struct because it is variable
  };
  struct aac_write_reply
@@@ -1826,9 -1823,12 +1826,12 @@@ int aac_send_shutdown(struct aac_dev *d
  int aac_probe_container(struct aac_dev *dev, int cid);
  int _aac_rx_init(struct aac_dev *dev);
  int aac_rx_select_comm(struct aac_dev *dev, int comm);
+ int aac_rx_deliver_producer(struct fib * fib);
  extern int numacb;
  extern int acbsize;
  extern char aac_driver_version[];
  extern int startup_timeout;
  extern int aif_timeout;
  extern int expose_physicals;
+ extern int aac_reset_devices;
+ extern int aac_commit;
diff --combined drivers/scsi/ipr.c
index 6411c458d336487f48c52f07f6e4900d5012ed0b,fa6ff295e5683b544ceea30250de287fbdb362d6..072f5771565823284eaa5c273203facc2d9bf027
@@@ -539,6 -539,32 +539,6 @@@ struct ipr_cmnd *ipr_get_free_ipr_cmnd(
        return ipr_cmd;
  }
  
 -/**
 - * ipr_unmap_sglist - Unmap scatterlist if mapped
 - * @ioa_cfg:  ioa config struct
 - * @ipr_cmd:  ipr command struct
 - *
 - * Return value:
 - *    nothing
 - **/
 -static void ipr_unmap_sglist(struct ipr_ioa_cfg *ioa_cfg,
 -                           struct ipr_cmnd *ipr_cmd)
 -{
 -      struct scsi_cmnd *scsi_cmd = ipr_cmd->scsi_cmd;
 -
 -      if (ipr_cmd->dma_use_sg) {
 -              if (scsi_cmd->use_sg > 0) {
 -                      pci_unmap_sg(ioa_cfg->pdev, scsi_cmd->request_buffer,
 -                                   scsi_cmd->use_sg,
 -                                   scsi_cmd->sc_data_direction);
 -              } else {
 -                      pci_unmap_single(ioa_cfg->pdev, ipr_cmd->dma_handle,
 -                                       scsi_cmd->request_bufflen,
 -                                       scsi_cmd->sc_data_direction);
 -              }
 -      }
 -}
 -
  /**
   * ipr_mask_and_clear_interrupts - Mask all and clear specified interrupts
   * @ioa_cfg:  ioa config struct
@@@ -651,7 -677,7 +651,7 @@@ static void ipr_scsi_eh_done(struct ipr
  
        scsi_cmd->result |= (DID_ERROR << 16);
  
 -      ipr_unmap_sglist(ioa_cfg, ipr_cmd);
 +      scsi_dma_unmap(ipr_cmd->scsi_cmd);
        scsi_cmd->scsi_done(scsi_cmd);
        list_add_tail(&ipr_cmd->queue, &ioa_cfg->free_q);
  }
@@@ -3928,6 -3954,13 +3928,13 @@@ static int __ipr_eh_dev_reset(struct sc
                spin_unlock_irq(scsi_cmd->device->host->host_lock);
                ata_do_eh(ap, NULL, NULL, ipr_sata_reset, NULL);
                spin_lock_irq(scsi_cmd->device->host->host_lock);
+               list_for_each_entry(ipr_cmd, &ioa_cfg->pending_q, queue) {
+                       if (ipr_cmd->ioarcb.res_handle == res->cfgte.res_handle) {
+                               rc = -EIO;
+                               break;
+                       }
+               }
        } else
                rc = ipr_device_reset(ioa_cfg, res);
        res->resetting_device = 0;
@@@ -4259,55 -4292,93 +4266,55 @@@ static irqreturn_t ipr_isr(int irq, voi
  static int ipr_build_ioadl(struct ipr_ioa_cfg *ioa_cfg,
                           struct ipr_cmnd *ipr_cmd)
  {
 -      int i;
 -      struct scatterlist *sglist;
 +      int i, nseg;
 +      struct scatterlist *sg;
        u32 length;
        u32 ioadl_flags = 0;
        struct scsi_cmnd *scsi_cmd = ipr_cmd->scsi_cmd;
        struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb;
        struct ipr_ioadl_desc *ioadl = ipr_cmd->ioadl;
  
 -      length = scsi_cmd->request_bufflen;
 -
 -      if (length == 0)
 +      length = scsi_bufflen(scsi_cmd);
 +      if (!length)
                return 0;
  
 -      if (scsi_cmd->use_sg) {
 -              ipr_cmd->dma_use_sg = pci_map_sg(ioa_cfg->pdev,
 -                                               scsi_cmd->request_buffer,
 -                                               scsi_cmd->use_sg,
 -                                               scsi_cmd->sc_data_direction);
 -
 -              if (scsi_cmd->sc_data_direction == DMA_TO_DEVICE) {
 -                      ioadl_flags = IPR_IOADL_FLAGS_WRITE;
 -                      ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_WRITE_NOT_READ;
 -                      ioarcb->write_data_transfer_length = cpu_to_be32(length);
 -                      ioarcb->write_ioadl_len =
 -                              cpu_to_be32(sizeof(struct ipr_ioadl_desc) * ipr_cmd->dma_use_sg);
 -              } else if (scsi_cmd->sc_data_direction == DMA_FROM_DEVICE) {
 -                      ioadl_flags = IPR_IOADL_FLAGS_READ;
 -                      ioarcb->read_data_transfer_length = cpu_to_be32(length);
 -                      ioarcb->read_ioadl_len =
 -                              cpu_to_be32(sizeof(struct ipr_ioadl_desc) * ipr_cmd->dma_use_sg);
 -              }
 -
 -              sglist = scsi_cmd->request_buffer;
 -
 -              if (ipr_cmd->dma_use_sg <= ARRAY_SIZE(ioarcb->add_data.u.ioadl)) {
 -                      ioadl = ioarcb->add_data.u.ioadl;
 -                      ioarcb->write_ioadl_addr =
 -                              cpu_to_be32(be32_to_cpu(ioarcb->ioarcb_host_pci_addr) +
 -                                          offsetof(struct ipr_ioarcb, add_data));
 -                      ioarcb->read_ioadl_addr = ioarcb->write_ioadl_addr;
 -              }
 +      nseg = scsi_dma_map(scsi_cmd);
 +      if (nseg < 0) {
 +              dev_err(&ioa_cfg->pdev->dev, "pci_map_sg failed!\n");
 +              return -1;
 +      }
  
 -              for (i = 0; i < ipr_cmd->dma_use_sg; i++) {
 -                      ioadl[i].flags_and_data_len =
 -                              cpu_to_be32(ioadl_flags | sg_dma_len(&sglist[i]));
 -                      ioadl[i].address =
 -                              cpu_to_be32(sg_dma_address(&sglist[i]));
 -              }
 +      ipr_cmd->dma_use_sg = nseg;
 +
 +      if (scsi_cmd->sc_data_direction == DMA_TO_DEVICE) {
 +              ioadl_flags = IPR_IOADL_FLAGS_WRITE;
 +              ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_WRITE_NOT_READ;
 +              ioarcb->write_data_transfer_length = cpu_to_be32(length);
 +              ioarcb->write_ioadl_len =
 +                      cpu_to_be32(sizeof(struct ipr_ioadl_desc) * ipr_cmd->dma_use_sg);
 +      } else if (scsi_cmd->sc_data_direction == DMA_FROM_DEVICE) {
 +              ioadl_flags = IPR_IOADL_FLAGS_READ;
 +              ioarcb->read_data_transfer_length = cpu_to_be32(length);
 +              ioarcb->read_ioadl_len =
 +                      cpu_to_be32(sizeof(struct ipr_ioadl_desc) * ipr_cmd->dma_use_sg);
 +      }
  
 -              if (likely(ipr_cmd->dma_use_sg)) {
 -                      ioadl[i-1].flags_and_data_len |=
 -                              cpu_to_be32(IPR_IOADL_FLAGS_LAST);
 -                      return 0;
 -              } else
 -                      dev_err(&ioa_cfg->pdev->dev, "pci_map_sg failed!\n");
 -      } else {
 -              if (scsi_cmd->sc_data_direction == DMA_TO_DEVICE) {
 -                      ioadl_flags = IPR_IOADL_FLAGS_WRITE;
 -                      ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_WRITE_NOT_READ;
 -                      ioarcb->write_data_transfer_length = cpu_to_be32(length);
 -                      ioarcb->write_ioadl_len = cpu_to_be32(sizeof(struct ipr_ioadl_desc));
 -              } else if (scsi_cmd->sc_data_direction == DMA_FROM_DEVICE) {
 -                      ioadl_flags = IPR_IOADL_FLAGS_READ;
 -                      ioarcb->read_data_transfer_length = cpu_to_be32(length);
 -                      ioarcb->read_ioadl_len = cpu_to_be32(sizeof(struct ipr_ioadl_desc));
 -              }
 +      if (ipr_cmd->dma_use_sg <= ARRAY_SIZE(ioarcb->add_data.u.ioadl)) {
 +              ioadl = ioarcb->add_data.u.ioadl;
 +              ioarcb->write_ioadl_addr =
 +                      cpu_to_be32(be32_to_cpu(ioarcb->ioarcb_host_pci_addr) +
 +                                  offsetof(struct ipr_ioarcb, add_data));
 +              ioarcb->read_ioadl_addr = ioarcb->write_ioadl_addr;
 +      }
  
 -              ipr_cmd->dma_handle = pci_map_single(ioa_cfg->pdev,
 -                                                   scsi_cmd->request_buffer, length,
 -                                                   scsi_cmd->sc_data_direction);
 -
 -              if (likely(!pci_dma_mapping_error(ipr_cmd->dma_handle))) {
 -                      ioadl = ioarcb->add_data.u.ioadl;
 -                      ioarcb->write_ioadl_addr =
 -                              cpu_to_be32(be32_to_cpu(ioarcb->ioarcb_host_pci_addr) +
 -                                          offsetof(struct ipr_ioarcb, add_data));
 -                      ioarcb->read_ioadl_addr = ioarcb->write_ioadl_addr;
 -                      ipr_cmd->dma_use_sg = 1;
 -                      ioadl[0].flags_and_data_len =
 -                              cpu_to_be32(ioadl_flags | length | IPR_IOADL_FLAGS_LAST);
 -                      ioadl[0].address = cpu_to_be32(ipr_cmd->dma_handle);
 -                      return 0;
 -              } else
 -                      dev_err(&ioa_cfg->pdev->dev, "pci_map_single failed!\n");
 +      scsi_for_each_sg(scsi_cmd, sg, ipr_cmd->dma_use_sg, i) {
 +              ioadl[i].flags_and_data_len =
 +                      cpu_to_be32(ioadl_flags | sg_dma_len(sg));
 +              ioadl[i].address = cpu_to_be32(sg_dma_address(sg));
        }
  
 -      return -1;
 +      ioadl[i-1].flags_and_data_len |= cpu_to_be32(IPR_IOADL_FLAGS_LAST);
 +      return 0;
  }
  
  /**
@@@ -4370,7 -4441,7 +4377,7 @@@ static void ipr_erp_done(struct ipr_cmn
                        res->needs_sync_complete = 1;
                res->in_erp = 0;
        }
 -      ipr_unmap_sglist(ioa_cfg, ipr_cmd);
 +      scsi_dma_unmap(ipr_cmd->scsi_cmd);
        list_add_tail(&ipr_cmd->queue, &ioa_cfg->free_q);
        scsi_cmd->scsi_done(scsi_cmd);
  }
@@@ -4748,7 -4819,7 +4755,7 @@@ static void ipr_erp_start(struct ipr_io
                break;
        }
  
 -      ipr_unmap_sglist(ioa_cfg, ipr_cmd);
 +      scsi_dma_unmap(ipr_cmd->scsi_cmd);
        list_add_tail(&ipr_cmd->queue, &ioa_cfg->free_q);
        scsi_cmd->scsi_done(scsi_cmd);
  }
@@@ -4769,10 -4840,10 +4776,10 @@@ static void ipr_scsi_done(struct ipr_cm
        struct scsi_cmnd *scsi_cmd = ipr_cmd->scsi_cmd;
        u32 ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc);
  
 -      scsi_cmd->resid = be32_to_cpu(ipr_cmd->ioasa.residual_data_len);
 +      scsi_set_resid(scsi_cmd, be32_to_cpu(ipr_cmd->ioasa.residual_data_len));
  
        if (likely(IPR_IOASC_SENSE_KEY(ioasc) == 0)) {
 -              ipr_unmap_sglist(ioa_cfg, ipr_cmd);
 +              scsi_dma_unmap(ipr_cmd->scsi_cmd);
                list_add_tail(&ipr_cmd->queue, &ioa_cfg->free_q);
                scsi_cmd->scsi_done(scsi_cmd);
        } else
diff --combined drivers/scsi/sd.c
index f071b9edaf360f949e8d8571f8986739cda237d5,3d8c9cb24f9187d6f0e4f487c4eae7878036b332..448d316f12d780a8d78ffb126ec071926b898c97
@@@ -1515,7 -1515,7 +1515,7 @@@ static int sd_revalidate_disk(struct ge
        if (!scsi_device_online(sdp))
                goto out;
  
 -      buffer = kmalloc(SD_BUF_SIZE, GFP_KERNEL | __GFP_DMA);
 +      buffer = kmalloc(SD_BUF_SIZE, GFP_KERNEL);
        if (!buffer) {
                sd_printk(KERN_WARNING, sdkp, "sd_revalidate_disk: Memory "
                          "allocation failure.\n");
@@@ -1789,7 -1789,7 +1789,7 @@@ static void sd_shutdown(struct device *
  static int sd_suspend(struct device *dev, pm_message_t mesg)
  {
        struct scsi_disk *sdkp = scsi_disk_get_from_dev(dev);
-       int ret;
+       int ret = 0;
  
        if (!sdkp)
                return 0;       /* this can happen */
                sd_printk(KERN_NOTICE, sdkp, "Synchronizing SCSI cache\n");
                ret = sd_sync_cache(sdkp);
                if (ret)
-                       return ret;
+                       goto done;
        }
  
        if (mesg.event == PM_EVENT_SUSPEND &&
            sdkp->device->manage_start_stop) {
                sd_printk(KERN_NOTICE, sdkp, "Stopping disk\n");
                ret = sd_start_stop_device(sdkp, 0);
-               if (ret)
-                       return ret;
        }
  
-       return 0;
+ done:
+       scsi_disk_put(sdkp);
+       return ret;
  }
  
  static int sd_resume(struct device *dev)
  {
        struct scsi_disk *sdkp = scsi_disk_get_from_dev(dev);
+       int ret = 0;
  
        if (!sdkp->device->manage_start_stop)
-               return 0;
+               goto done;
  
        sd_printk(KERN_NOTICE, sdkp, "Starting disk\n");
+       ret = sd_start_stop_device(sdkp, 1);
  
-       return sd_start_stop_device(sdkp, 1);
+ done:
+       scsi_disk_put(sdkp);
+       return ret;
  }
  
  /**
diff --combined drivers/scsi/stex.c
index baf516d09d79d469bfe11df03e7fd2dd68bc6f53,9ac83abc4028c2ec33cd80941e0bda1050003d0c..adda296b594bfbd2389081990e441f1497802a15
  #include <scsi/scsi_cmnd.h>
  #include <scsi/scsi_host.h>
  #include <scsi/scsi_tcq.h>
+ #include <scsi/scsi_dbg.h>
  
  #define DRV_NAME "stex"
- #define ST_DRIVER_VERSION "3.1.0.1"
+ #define ST_DRIVER_VERSION "3.6.0000.1"
  #define ST_VER_MAJOR          3
- #define ST_VER_MINOR          1
+ #define ST_VER_MINOR          6
  #define ST_OEM                        0
  #define ST_BUILD_VER          1
  
@@@ -113,10 -114,6 +114,6 @@@ enum 
        SG_CF_64B                               = 0x40, /* 64 bit item */
        SG_CF_HOST                              = 0x20, /* sg in host memory */
  
-       ST_MAX_ARRAY_SUPPORTED                  = 16,
-       ST_MAX_TARGET_NUM                       = (ST_MAX_ARRAY_SUPPORTED+1),
-       ST_MAX_LUN_PER_TARGET                   = 16,
        st_shasta                               = 0,
        st_vsc                                  = 1,
        st_vsc1                                 = 2,
@@@ -398,34 -395,53 +395,34 @@@ static struct req_msg *stex_alloc_req(s
  static int stex_map_sg(struct st_hba *hba,
        struct req_msg *req, struct st_ccb *ccb)
  {
 -      struct pci_dev *pdev = hba->pdev;
        struct scsi_cmnd *cmd;
 -      dma_addr_t dma_handle;
 -      struct scatterlist *src;
 +      struct scatterlist *sg;
        struct st_sgtable *dst;
 -      int i;
 +      int i, nseg;
  
        cmd = ccb->cmd;
        dst = (struct st_sgtable *)req->variable;
        dst->max_sg_count = cpu_to_le16(ST_MAX_SG);
 -      dst->sz_in_byte = cpu_to_le32(cmd->request_bufflen);
 -
 -      if (cmd->use_sg) {
 -              int n_elem;
 +      dst->sz_in_byte = cpu_to_le32(scsi_bufflen(cmd));
  
 -              src = (struct scatterlist *) cmd->request_buffer;
 -              n_elem = pci_map_sg(pdev, src,
 -                      cmd->use_sg, cmd->sc_data_direction);
 -              if (n_elem <= 0)
 -                      return -EIO;
 +      nseg = scsi_dma_map(cmd);
 +      if (nseg < 0)
 +              return -EIO;
 +      if (nseg) {
 +              ccb->sg_count = nseg;
 +              dst->sg_count = cpu_to_le16((u16)nseg);
  
 -              ccb->sg_count = n_elem;
 -              dst->sg_count = cpu_to_le16((u16)n_elem);
 -
 -              for (i = 0; i < n_elem; i++, src++) {
 -                      dst->table[i].count = cpu_to_le32((u32)sg_dma_len(src));
 +              scsi_for_each_sg(cmd, sg, nseg, i) {
 +                      dst->table[i].count = cpu_to_le32((u32)sg_dma_len(sg));
                        dst->table[i].addr =
 -                              cpu_to_le32(sg_dma_address(src) & 0xffffffff);
 +                              cpu_to_le32(sg_dma_address(sg) & 0xffffffff);
                        dst->table[i].addr_hi =
 -                              cpu_to_le32((sg_dma_address(src) >> 16) >> 16);
 +                              cpu_to_le32((sg_dma_address(sg) >> 16) >> 16);
                        dst->table[i].ctrl = SG_CF_64B | SG_CF_HOST;
                }
                dst->table[--i].ctrl |= SG_CF_EOT;
 -              return 0;
        }
  
 -      dma_handle = pci_map_single(pdev, cmd->request_buffer,
 -              cmd->request_bufflen, cmd->sc_data_direction);
 -      cmd->SCp.dma_handle = dma_handle;
 -
 -      ccb->sg_count = 1;
 -      dst->sg_count = cpu_to_le16(1);
 -      dst->table[0].addr = cpu_to_le32(dma_handle & 0xffffffff);
 -      dst->table[0].addr_hi = cpu_to_le32((dma_handle >> 16) >> 16);
 -      dst->table[0].count = cpu_to_le32((u32)cmd->request_bufflen);
 -      dst->table[0].ctrl = SG_CF_EOT | SG_CF_64B | SG_CF_HOST;
 -
        return 0;
  }
  
@@@ -435,24 -451,24 +432,24 @@@ static void stex_internal_copy(struct s
        size_t lcount;
        size_t len;
        void *s, *d, *base = NULL;
 -      if (*count > cmd->request_bufflen)
 -              *count = cmd->request_bufflen;
 +      size_t offset;
 +
 +      if (*count > scsi_bufflen(cmd))
 +              *count = scsi_bufflen(cmd);
        lcount = *count;
        while (lcount) {
                len = lcount;
                s = (void *)src;
 -              if (cmd->use_sg) {
 -                      size_t offset = *count - lcount;
 -                      s += offset;
 -                      base = scsi_kmap_atomic_sg(cmd->request_buffer,
 -                              sg_count, &offset, &len);
 -                      if (base == NULL) {
 -                              *count -= lcount;
 -                              return;
 -                      }
 -                      d = base + offset;
 -              } else
 -                      d = cmd->request_buffer;
 +
 +              offset = *count - lcount;
 +              s += offset;
 +              base = scsi_kmap_atomic_sg(scsi_sglist(cmd),
 +                                         sg_count, &offset, &len);
 +              if (!base) {
 +                      *count -= lcount;
 +                      return;
 +              }
 +              d = base + offset;
  
                if (direction == ST_TO_CMD)
                        memcpy(d, s, len);
                        memcpy(s, d, len);
  
                lcount -= len;
 -              if (cmd->use_sg)
 -                      scsi_kunmap_atomic_sg(base);
 +              scsi_kunmap_atomic_sg(base);
        }
  }
  
  static int stex_direct_copy(struct scsi_cmnd *cmd,
        const void *src, size_t count)
  {
 -      struct st_hba *hba = (struct st_hba *) &cmd->device->host->hostdata[0];
        size_t cp_len = count;
        int n_elem = 0;
  
 -      if (cmd->use_sg) {
 -              n_elem = pci_map_sg(hba->pdev, cmd->request_buffer,
 -                      cmd->use_sg, cmd->sc_data_direction);
 -              if (n_elem <= 0)
 -                      return 0;
 -      }
 +      n_elem = scsi_dma_map(cmd);
 +      if (n_elem < 0)
 +              return 0;
  
        stex_internal_copy(cmd, src, &cp_len, n_elem, ST_TO_CMD);
  
 -      if (cmd->use_sg)
 -              pci_unmap_sg(hba->pdev, cmd->request_buffer,
 -                      cmd->use_sg, cmd->sc_data_direction);
 +      scsi_dma_unmap(cmd);
 +
        return cp_len == count;
  }
  
@@@ -561,7 -583,7 +558,7 @@@ stex_queuecommand(struct scsi_cmnd *cmd
        u16 tag;
        host = cmd->device->host;
        id = cmd->device->id;
-       lun = cmd->device->channel; /* firmware lun issue work around */
+       lun = cmd->device->lun;
        hba = (struct st_hba *) &host->hostdata[0];
  
        switch (cmd->cmnd[0]) {
                        stex_invalid_field(cmd, done);
                return 0;
        }
+       case REPORT_LUNS:
+               /*
+                * The shasta firmware does not report actual luns in the
+                * target, so fail the command to force sequential lun scan.
+                * Also, the console device does not support this command.
+                */
+               if (hba->cardtype == st_shasta || id == host->max_id - 1) {
+                       stex_invalid_field(cmd, done);
+                       return 0;
+               }
+               break;
+       case TEST_UNIT_READY:
+               if (id == host->max_id - 1) {
+                       cmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8;
+                       done(cmd);
+                       return 0;
+               }
+               break;
        case INQUIRY:
-               if (id != ST_MAX_ARRAY_SUPPORTED)
+               if (id != host->max_id - 1)
                        break;
                if (lun == 0 && (cmd->cmnd[1] & INQUIRY_EVPD) == 0) {
                        stex_direct_copy(cmd, console_inq_page,
                        ver.oem = ST_OEM;
                        ver.build = ST_BUILD_VER;
                        ver.signature[0] = PASSTHRU_SIGNATURE;
-                       ver.console_id = ST_MAX_ARRAY_SUPPORTED;
+                       ver.console_id = host->max_id - 1;
                        ver.host_no = hba->host->host_no;
                        cmd->result = stex_direct_copy(cmd, &ver, sizeof(ver)) ?
                                DID_OK << 16 | COMMAND_COMPLETE << 8 :
  
        req = stex_alloc_req(hba);
  
-       if (hba->cardtype == st_yosemite) {
-               req->lun = lun * (ST_MAX_TARGET_NUM - 1) + id;
-               req->target = 0;
-       } else {
-               req->lun = lun;
-               req->target = id;
-       }
+       req->lun = lun;
+       req->target = id;
  
        /* cdb */
        memcpy(req->cdb, cmd->cmnd, STEX_CDB_LENGTH);
        return 0;
  }
  
 -static void stex_unmap_sg(struct st_hba *hba, struct scsi_cmnd *cmd)
 -{
 -      if (cmd->sc_data_direction != DMA_NONE) {
 -              if (cmd->use_sg)
 -                      pci_unmap_sg(hba->pdev, cmd->request_buffer,
 -                              cmd->use_sg, cmd->sc_data_direction);
 -              else
 -                      pci_unmap_single(hba->pdev, cmd->SCp.dma_handle,
 -                              cmd->request_bufflen, cmd->sc_data_direction);
 -      }
 -}
 -
  static void stex_scsi_done(struct st_ccb *ccb)
  {
        struct scsi_cmnd *cmd = ccb->cmd;
@@@ -709,7 -756,7 +719,7 @@@ static void stex_ys_commands(struct st_
  
        if (ccb->cmd->cmnd[0] == MGT_CMD &&
                resp->scsi_status != SAM_STAT_CHECK_CONDITION) {
 -              ccb->cmd->request_bufflen =
 +              scsi_bufflen(ccb->cmd) =
                        le32_to_cpu(*(__le32 *)&resp->variable[0]);
                return;
        }
                        ccb->srb_status = SRB_STATUS_SELECTION_TIMEOUT;
                else
                        ccb->srb_status = SRB_STATUS_SUCCESS;
-       } else if (ccb->cmd->cmnd[0] == REPORT_LUNS) {
-               u8 *report_lun_data = (u8 *)hba->copy_buffer;
-               count = STEX_EXTRA_SIZE;
-               stex_internal_copy(ccb->cmd, report_lun_data,
-                       &count, ccb->sg_count, ST_FROM_CMD);
-               if (report_lun_data[2] || report_lun_data[3]) {
-                       report_lun_data[2] = 0x00;
-                       report_lun_data[3] = 0x08;
-                       stex_internal_copy(ccb->cmd, report_lun_data,
-                               &count, ccb->sg_count, ST_TO_CMD);
-               }
        }
  }
  
@@@ -820,7 -855,7 +818,7 @@@ static void stex_mu_intr(struct st_hba 
                                ccb->cmd->cmnd[1] == PASSTHRU_GET_ADAPTER))
                                stex_controller_info(hba, ccb);
  
 -                      stex_unmap_sg(hba, ccb->cmd);
 +                      scsi_dma_unmap(ccb->cmd);
                        stex_scsi_done(ccb);
                        hba->out_req_cnt--;
                } else if (ccb->req_type & PASSTHRU_REQ_TYPE) {
@@@ -958,6 -993,11 +956,11 @@@ static int stex_abort(struct scsi_cmnd 
        u32 data;
        int result = SUCCESS;
        unsigned long flags;
+       printk(KERN_INFO DRV_NAME
+               "(%s): aborting command\n", pci_name(hba->pdev));
+       scsi_print_command(cmd);
        base = hba->mmio_base;
        spin_lock_irqsave(host->host_lock, flags);
        if (tag < host->can_queue && hba->ccb[tag].cmd == cmd)
        }
  
  fail_out:
 -      stex_unmap_sg(hba, cmd);
 +      scsi_dma_unmap(cmd);
        hba->wait_ccb->req = NULL; /* nullify the req's future return */
        hba->wait_ccb = NULL;
        result = FAILED;
@@@ -1014,7 -1054,12 +1017,12 @@@ static void stex_hard_reset(struct st_h
        pci_read_config_byte(bus->self, PCI_BRIDGE_CONTROL, &pci_bctl);
        pci_bctl |= PCI_BRIDGE_CTL_BUS_RESET;
        pci_write_config_byte(bus->self, PCI_BRIDGE_CONTROL, pci_bctl);
-       msleep(1);
+       /*
+        * 1 ms may be enough for 8-port controllers. But 16-port controllers
+        * require more time to finish bus reset. Use 100 ms here for safety
+        */
+       msleep(100);
        pci_bctl &= ~PCI_BRIDGE_CTL_BUS_RESET;
        pci_write_config_byte(bus->self, PCI_BRIDGE_CONTROL, pci_bctl);
  
@@@ -1038,6 -1083,10 +1046,10 @@@ static int stex_reset(struct scsi_cmnd 
        unsigned long before;
        hba = (struct st_hba *) &cmd->device->host->hostdata[0];
  
+       printk(KERN_INFO DRV_NAME
+               "(%s): resetting host\n", pci_name(hba->pdev));
+       scsi_print_command(cmd);
        hba->mu_status = MU_STATE_RESETTING;
  
        if (hba->cardtype == st_shasta)
@@@ -1157,7 -1206,7 +1169,7 @@@ stex_probe(struct pci_dev *pdev, const 
                goto out_scsi_host_put;
        }
  
-       hba->mmio_base = ioremap(pci_resource_start(pdev, 0),
+       hba->mmio_base = ioremap_nocache(pci_resource_start(pdev, 0),
                pci_resource_len(pdev, 0));
        if ( !hba->mmio_base) {
                printk(KERN_ERR DRV_NAME "(%s): memory map failed\n",
        hba->copy_buffer = hba->dma_mem + MU_BUFFER_SIZE;
        hba->mu_status = MU_STATE_STARTING;
  
-       /* firmware uses id/lun pair for a logical drive, but lun would be
-          always 0 if CONFIG_SCSI_MULTI_LUN not configured, so we use
-          channel to map lun here */
-       host->max_channel = ST_MAX_LUN_PER_TARGET - 1;
-       host->max_id = ST_MAX_TARGET_NUM;
-       host->max_lun = 1;
+       if (hba->cardtype == st_shasta) {
+               host->max_lun = 8;
+               host->max_id = 16 + 1;
+       } else if (hba->cardtype == st_yosemite) {
+               host->max_lun = 128;
+               host->max_id = 1 + 1;
+       } else {
+               /* st_vsc and st_vsc1 */
+               host->max_lun = 1;
+               host->max_id = 128 + 1;
+       }
+       host->max_channel = 0;
        host->unique_id = host->host_no;
        host->max_cmd_len = STEX_CDB_LENGTH;