Merge tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 15 Mar 2017 17:44:19 +0000 (10:44 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 15 Mar 2017 17:44:19 +0000 (10:44 -0700)
Pull SCSI fixes from James Bottomley:
 "This is a rather large set of fixes. The bulk are for lpfc correcting
  a lot of issues in the new NVME driver code which just went in in the
  merge window.

  The others are:

   - fix a hang in the vmware paravirt driver caused by incorrect
     handling of the new MSI vector allocation

   - long standing bug in storvsc, which recent block changes turned
     from being a harmless annoyance into a hang

   - yet more fallout (in mpt3sas) from the changes to device blocking

  The remainder are small fixes and updates"

* tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: (34 commits)
  scsi: lpfc: Add shutdown method for kexec
  scsi: storvsc: Workaround for virtual DVD SCSI version
  scsi: lpfc: revise version number to 11.2.0.10
  scsi: lpfc: code cleanups in NVME initiator discovery
  scsi: lpfc: code cleanups in NVME initiator base
  scsi: lpfc: correct rdp diag portnames
  scsi: lpfc: remove dead sli3 nvme code
  scsi: lpfc: correct double print
  scsi: lpfc: Rename LPFC_MAX_EQ_DELAY to LPFC_MAX_EQ_DELAY_EQID_CNT
  scsi: lpfc: Rework lpfc Kconfig for NVME options
  scsi: lpfc: add transport eh_timed_out reference
  scsi: lpfc: Fix eh_deadline setting for sli3 adapters.
  scsi: lpfc: add NVME exchange aborts
  scsi: lpfc: Fix nvme allocation bug on failed nvme_fc_register_localport
  scsi: lpfc: Fix IO submission if WQ is full
  scsi: lpfc: Fix NVME CMD IU byte swapped word 1 problem
  scsi: lpfc: Fix RCTL value on NVME LS request and response
  scsi: lpfc: Fix crash during Hardware error recovery on SLI3 adapters
  scsi: lpfc: fix missing spin_unlock on sql_list_lock
  scsi: lpfc: don't dereference dma_buf->iocbq before null check
  ...

1  2 
drivers/scsi/sd.c

diff --combined drivers/scsi/sd.c
index d277e8620e3e39794584ac29dc55cc3ce476a03a,fb9b4d29af0b0394abac4169c53e292efc214725..fcfeddc79331bbf32a71e296cf606513ae5b3d78
@@@ -1783,6 -1783,8 +1783,8 @@@ static int sd_done(struct scsi_cmnd *SC
  {
        int result = SCpnt->result;
        unsigned int good_bytes = result ? 0 : scsi_bufflen(SCpnt);
+       unsigned int sector_size = SCpnt->device->sector_size;
+       unsigned int resid;
        struct scsi_sense_hdr sshdr;
        struct scsi_disk *sdkp = scsi_disk(SCpnt->request->rq_disk);
        struct request *req = SCpnt->request;
                        scsi_set_resid(SCpnt, blk_rq_bytes(req));
                }
                break;
+       default:
+               /*
+                * In case of bogus fw or device, we could end up having
+                * an unaligned partial completion. Check this here and force
+                * alignment.
+                */
+               resid = scsi_get_resid(SCpnt);
+               if (resid & (sector_size - 1)) {
+                       sd_printk(KERN_INFO, sdkp,
+                               "Unaligned partial completion (resid=%u, sector_sz=%u)\n",
+                               resid, sector_size);
+                       resid = min(scsi_bufflen(SCpnt),
+                                   round_up(resid, sector_size));
+                       scsi_set_resid(SCpnt, resid);
+               }
        }
  
        if (result) {
@@@ -3075,6 -3092,23 +3092,6 @@@ static void sd_probe_async(void *data, 
        put_device(&sdkp->dev);
  }
  
 -struct sd_devt {
 -      int idx;
 -      struct disk_devt disk_devt;
 -};
 -
 -static void sd_devt_release(struct disk_devt *disk_devt)
 -{
 -      struct sd_devt *sd_devt = container_of(disk_devt, struct sd_devt,
 -                      disk_devt);
 -
 -      spin_lock(&sd_index_lock);
 -      ida_remove(&sd_index_ida, sd_devt->idx);
 -      spin_unlock(&sd_index_lock);
 -
 -      kfree(sd_devt);
 -}
 -
  /**
   *    sd_probe - called during driver initialization and whenever a
   *    new scsi device is attached to the system. It is called once
  static int sd_probe(struct device *dev)
  {
        struct scsi_device *sdp = to_scsi_device(dev);
 -      struct sd_devt *sd_devt;
        struct scsi_disk *sdkp;
        struct gendisk *gd;
        int index;
        if (!sdkp)
                goto out;
  
 -      sd_devt = kzalloc(sizeof(*sd_devt), GFP_KERNEL);
 -      if (!sd_devt)
 -              goto out_free;
 -
        gd = alloc_disk(SD_MINORS);
        if (!gd)
 -              goto out_free_devt;
 +              goto out_free;
  
        do {
                if (!ida_pre_get(&sd_index_ida, GFP_KERNEL))
                goto out_put;
        }
  
 -      atomic_set(&sd_devt->disk_devt.count, 1);
 -      sd_devt->disk_devt.release = sd_devt_release;
 -      sd_devt->idx = index;
 -      gd->disk_devt = &sd_devt->disk_devt;
 -
        error = sd_format_disk_name("sd", index, gd->disk_name, DISK_NAME_LEN);
        if (error) {
                sdev_printk(KERN_WARNING, sdp, "SCSI disk (sd) name length exceeded.\n");
        return 0;
  
   out_free_index:
 -      put_disk_devt(&sd_devt->disk_devt);
 -      sd_devt = NULL;
 +      spin_lock(&sd_index_lock);
 +      ida_remove(&sd_index_ida, index);
 +      spin_unlock(&sd_index_lock);
   out_put:
        put_disk(gd);
 - out_free_devt:
 -      kfree(sd_devt);
   out_free:
        kfree(sdkp);
   out:
@@@ -3243,10 -3288,7 +3260,10 @@@ static void scsi_disk_release(struct de
        struct scsi_disk *sdkp = to_scsi_disk(dev);
        struct gendisk *disk = sdkp->disk;
        
 -      put_disk_devt(disk->disk_devt);
 +      spin_lock(&sd_index_lock);
 +      ida_remove(&sd_index_ida, sdkp->index);
 +      spin_unlock(&sd_index_lock);
 +
        disk->private_data = NULL;
        put_disk(disk);
        put_device(&sdkp->device->sdev_gendev);