Merge remote-tracking branch 'mkp-scsi/4.5/scsi-fixes' into fixes
authorJames Bottomley <James.Bottomley@HansenPartnership.com>
Fri, 5 Feb 2016 05:37:52 +0000 (21:37 -0800)
committerJames Bottomley <James.Bottomley@HansenPartnership.com>
Fri, 5 Feb 2016 05:37:52 +0000 (21:37 -0800)
1  2 
block/blk-core.c
drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
drivers/scsi/scsi_devinfo.c
drivers/scsi/sd.c
drivers/scsi/storvsc_drv.c
include/linux/blkdev.h

diff --combined block/blk-core.c
@@@ -680,13 -680,6 +680,13 @@@ static void blk_queue_usage_counter_rel
        wake_up_all(&q->mq_freeze_wq);
  }
  
 +static void blk_rq_timed_out_timer(unsigned long data)
 +{
 +      struct request_queue *q = (struct request_queue *)data;
 +
 +      kblockd_schedule_work(&q->timeout_work);
 +}
 +
  struct request_queue *blk_alloc_queue_node(gfp_t gfp_mask, int node_id)
  {
        struct request_queue *q;
@@@ -848,7 -841,6 +848,7 @@@ blk_init_allocated_queue(struct request
        if (blk_init_rl(&q->root_rl, q, GFP_KERNEL))
                goto fail;
  
 +      INIT_WORK(&q->timeout_work, blk_timeout_work);
        q->request_fn           = rfn;
        q->prep_rq_fn           = NULL;
        q->unprep_rq_fn         = NULL;
@@@ -2455,14 -2447,16 +2455,16 @@@ struct request *blk_peek_request(struc
  
                        rq = NULL;
                        break;
-               } else if (ret == BLKPREP_KILL) {
+               } else if (ret == BLKPREP_KILL || ret == BLKPREP_INVALID) {
+                       int err = (ret == BLKPREP_INVALID) ? -EREMOTEIO : -EIO;
                        rq->cmd_flags |= REQ_QUIET;
                        /*
                         * Mark this request as started so we don't trigger
                         * any debug logic in the end I/O path.
                         */
                        blk_start_request(rq);
-                       __blk_end_request_all(rq, -EIO);
+                       __blk_end_request_all(rq, err);
                } else {
                        printk(KERN_ERR "%s: bad return=%d\n", __func__, ret);
                        break;
  /* ITCT header */
  /* qw0 */
  #define ITCT_HDR_DEV_TYPE_OFF         0
 -#define ITCT_HDR_DEV_TYPE_MSK         (0x3 << ITCT_HDR_DEV_TYPE_OFF)
 +#define ITCT_HDR_DEV_TYPE_MSK         (0x3ULL << ITCT_HDR_DEV_TYPE_OFF)
  #define ITCT_HDR_VALID_OFF            2
 -#define ITCT_HDR_VALID_MSK            (0x1 << ITCT_HDR_VALID_OFF)
 -#define ITCT_HDR_BREAK_REPLY_ENA_OFF  3
 -#define ITCT_HDR_BREAK_REPLY_ENA_MSK  (0x1 << ITCT_HDR_BREAK_REPLY_ENA_OFF)
 +#define ITCT_HDR_VALID_MSK            (0x1ULL << ITCT_HDR_VALID_OFF)
  #define ITCT_HDR_AWT_CONTROL_OFF      4
 -#define ITCT_HDR_AWT_CONTROL_MSK      (0x1 << ITCT_HDR_AWT_CONTROL_OFF)
 +#define ITCT_HDR_AWT_CONTROL_MSK      (0x1ULL << ITCT_HDR_AWT_CONTROL_OFF)
  #define ITCT_HDR_MAX_CONN_RATE_OFF    5
 -#define ITCT_HDR_MAX_CONN_RATE_MSK    (0xf << ITCT_HDR_MAX_CONN_RATE_OFF)
 +#define ITCT_HDR_MAX_CONN_RATE_MSK    (0xfULL << ITCT_HDR_MAX_CONN_RATE_OFF)
  #define ITCT_HDR_VALID_LINK_NUM_OFF   9
 -#define ITCT_HDR_VALID_LINK_NUM_MSK   (0xf << ITCT_HDR_VALID_LINK_NUM_OFF)
 +#define ITCT_HDR_VALID_LINK_NUM_MSK   (0xfULL << ITCT_HDR_VALID_LINK_NUM_OFF)
  #define ITCT_HDR_PORT_ID_OFF          13
 -#define ITCT_HDR_PORT_ID_MSK          (0x7 << ITCT_HDR_PORT_ID_OFF)
 +#define ITCT_HDR_PORT_ID_MSK          (0x7ULL << ITCT_HDR_PORT_ID_OFF)
  #define ITCT_HDR_SMP_TIMEOUT_OFF      16
 -#define ITCT_HDR_SMP_TIMEOUT_MSK      (0xffff << ITCT_HDR_SMP_TIMEOUT_OFF)
 -#define ITCT_HDR_MAX_BURST_BYTES_OFF  16
 -#define ITCT_HDR_MAX_BURST_BYTES_MSK  (0xffffffff << \
 -                                      ITCT_MAX_BURST_BYTES_OFF)
 +#define ITCT_HDR_SMP_TIMEOUT_MSK      (0xffffULL << ITCT_HDR_SMP_TIMEOUT_OFF)
  /* qw1 */
  #define ITCT_HDR_MAX_SAS_ADDR_OFF     0
  #define ITCT_HDR_MAX_SAS_ADDR_MSK     (0xffffffffffffffff << \
                                        ITCT_HDR_MAX_SAS_ADDR_OFF)
  /* qw2 */
  #define ITCT_HDR_IT_NEXUS_LOSS_TL_OFF 0
 -#define ITCT_HDR_IT_NEXUS_LOSS_TL_MSK (0xffff << \
 +#define ITCT_HDR_IT_NEXUS_LOSS_TL_MSK (0xffffULL << \
                                        ITCT_HDR_IT_NEXUS_LOSS_TL_OFF)
  #define ITCT_HDR_BUS_INACTIVE_TL_OFF  16
 -#define ITCT_HDR_BUS_INACTIVE_TL_MSK  (0xffff << \
 +#define ITCT_HDR_BUS_INACTIVE_TL_MSK  (0xffffULL << \
                                        ITCT_HDR_BUS_INACTIVE_TL_OFF)
  #define ITCT_HDR_MAX_CONN_TL_OFF      32
 -#define ITCT_HDR_MAX_CONN_TL_MSK      (0xffff << \
 +#define ITCT_HDR_MAX_CONN_TL_MSK      (0xffffULL << \
                                        ITCT_HDR_MAX_CONN_TL_OFF)
  #define ITCT_HDR_REJ_OPEN_TL_OFF      48
 -#define ITCT_HDR_REJ_OPEN_TL_MSK      (0xffff << \
 -                                      ITCT_REJ_OPEN_TL_OFF)
 +#define ITCT_HDR_REJ_OPEN_TL_MSK      (0xffffULL << \
 +                                      ITCT_HDR_REJ_OPEN_TL_OFF)
  
  /* Err record header */
  #define ERR_HDR_DMA_TX_ERR_TYPE_OFF   0
@@@ -528,10 -533,10 +528,10 @@@ static void setup_itct_v1_hw(struct his
        itct->sas_addr = __swab64(itct->sas_addr);
  
        /* qw2 */
 -      itct->qw2 = cpu_to_le64((500 < ITCT_HDR_IT_NEXUS_LOSS_TL_OFF) |
 -                              (0xff00 < ITCT_HDR_BUS_INACTIVE_TL_OFF) |
 -                              (0xff00 < ITCT_HDR_MAX_CONN_TL_OFF) |
 -                              (0xff00 < ITCT_HDR_REJ_OPEN_TL_OFF));
 +      itct->qw2 = cpu_to_le64((500ULL << ITCT_HDR_IT_NEXUS_LOSS_TL_OFF) |
 +                              (0xff00ULL << ITCT_HDR_BUS_INACTIVE_TL_OFF) |
 +                              (0xff00ULL << ITCT_HDR_MAX_CONN_TL_OFF) |
 +                              (0xff00ULL << ITCT_HDR_REJ_OPEN_TL_OFF));
  }
  
  static void free_device_v1_hw(struct hisi_hba *hisi_hba,
  {
        u64 dev_id = sas_dev->device_id;
        struct hisi_sas_itct *itct = &hisi_hba->itct[dev_id];
 -      u32 qw0, reg_val = hisi_sas_read32(hisi_hba, CFG_AGING_TIME);
 +      u64 qw0;
 +      u32 reg_val = hisi_sas_read32(hisi_hba, CFG_AGING_TIME);
  
        reg_val |= CFG_AGING_TIME_ITCT_REL_MSK;
        hisi_sas_write32(hisi_hba, CFG_AGING_TIME, reg_val);
@@@ -1289,13 -1293,10 +1289,10 @@@ static int slot_complete_v1_hw(struct h
                goto out;
        }
  
-       if (cmplt_hdr_data & CMPLT_HDR_ERR_RCRD_XFRD_MSK) {
-               if (!(cmplt_hdr_data & CMPLT_HDR_CMD_CMPLT_MSK) ||
-                   !(cmplt_hdr_data & CMPLT_HDR_RSPNS_XFRD_MSK))
-                       ts->stat = SAS_DATA_OVERRUN;
-               else
-                       slot_err_v1_hw(hisi_hba, task, slot);
+       if (cmplt_hdr_data & CMPLT_HDR_ERR_RCRD_XFRD_MSK &&
+               !(cmplt_hdr_data & CMPLT_HDR_RSPNS_XFRD_MSK)) {
  
+               slot_err_v1_hw(hisi_hba, task, slot);
                goto out;
        }
  
@@@ -205,6 -205,7 +205,7 @@@ static struct 
        {"Intel", "Multi-Flex", NULL, BLIST_NO_RSOC},
        {"iRiver", "iFP Mass Driver", NULL, BLIST_NOT_LOCKABLE | BLIST_INQUIRY_36},
        {"LASOUND", "CDX7405", "3.10", BLIST_MAX5LUN | BLIST_SINGLELUN},
+       {"Marvell", "Console", NULL, BLIST_SKIP_VPD_PAGES},
        {"MATSHITA", "PD-1", NULL, BLIST_FORCELUN | BLIST_SINGLELUN},
        {"MATSHITA", "DMC-LC5", NULL, BLIST_NOT_LOCKABLE | BLIST_INQUIRY_36},
        {"MATSHITA", "DMC-LC40", NULL, BLIST_NOT_LOCKABLE | BLIST_INQUIRY_36},
        {"Promise", "VTrak E610f", NULL, BLIST_SPARSELUN | BLIST_NO_RSOC},
        {"Promise", "", NULL, BLIST_SPARSELUN},
        {"QNAP", "iSCSI Storage", NULL, BLIST_MAX_1024},
 +      {"SYNOLOGY", "iSCSI Storage", NULL, BLIST_MAX_1024},
        {"QUANTUM", "XP34301", "1071", BLIST_NOTQ},
        {"REGAL", "CDC-4X", NULL, BLIST_MAX5LUN | BLIST_SINGLELUN},
        {"SanDisk", "ImageMate CF-SD1", NULL, BLIST_FORCELUN},
diff --combined drivers/scsi/sd.c
@@@ -761,7 -761,7 +761,7 @@@ static int sd_setup_discard_cmnd(struc
                break;
  
        default:
-               ret = BLKPREP_KILL;
+               ret = BLKPREP_INVALID;
                goto out;
        }
  
@@@ -839,7 -839,7 +839,7 @@@ static int sd_setup_write_same_cmnd(str
        int ret;
  
        if (sdkp->device->no_write_same)
-               return BLKPREP_KILL;
+               return BLKPREP_INVALID;
  
        BUG_ON(bio_offset(bio) || bio_iovec(bio).bv_len != sdp->sector_size);
  
@@@ -3268,8 -3268,8 +3268,8 @@@ static int sd_suspend_common(struct dev
        struct scsi_disk *sdkp = dev_get_drvdata(dev);
        int ret = 0;
  
 -      if (!sdkp)
 -              return 0;       /* this can happen */
 +      if (!sdkp)      /* E.g.: runtime suspend following sd_remove() */
 +              return 0;
  
        if (sdkp->WCE && sdkp->media_present) {
                sd_printk(KERN_NOTICE, sdkp, "Synchronizing SCSI cache\n");
@@@ -3308,9 -3308,6 +3308,9 @@@ static int sd_resume(struct device *dev
  {
        struct scsi_disk *sdkp = dev_get_drvdata(dev);
  
 +      if (!sdkp)      /* E.g.: runtime resume at the start of sd_probe() */
 +              return 0;
 +
        if (!sdkp->device->manage_start_stop)
                return 0;
  
@@@ -42,6 -42,7 +42,7 @@@
  #include <scsi/scsi_devinfo.h>
  #include <scsi/scsi_dbg.h>
  #include <scsi/scsi_transport_fc.h>
+ #include <scsi/scsi_transport.h>
  
  /*
   * All wire protocol details (storage protocol between the guest and the host)
@@@ -390,7 -391,7 +391,7 @@@ module_param(storvsc_ringbuffer_size, i
  MODULE_PARM_DESC(storvsc_ringbuffer_size, "Ring buffer size (bytes)");
  
  module_param(storvsc_vcpus_per_sub_channel, int, S_IRUGO);
 -MODULE_PARM_DESC(vcpus_per_sub_channel, "Ratio of VCPUs to subchannels");
 +MODULE_PARM_DESC(storvsc_vcpus_per_sub_channel, "Ratio of VCPUs to subchannels");
  /*
   * Timeout in seconds for all devices managed by this driver.
   */
@@@ -477,19 -478,18 +478,18 @@@ struct hv_host_device 
  struct storvsc_scan_work {
        struct work_struct work;
        struct Scsi_Host *host;
-       uint lun;
+       u8 lun;
+       u8 tgt_id;
  };
  
  static void storvsc_device_scan(struct work_struct *work)
  {
        struct storvsc_scan_work *wrk;
-       uint lun;
        struct scsi_device *sdev;
  
        wrk = container_of(work, struct storvsc_scan_work, work);
-       lun = wrk->lun;
  
-       sdev = scsi_device_lookup(wrk->host, 0, 0, lun);
+       sdev = scsi_device_lookup(wrk->host, 0, wrk->tgt_id, wrk->lun);
        if (!sdev)
                goto done;
        scsi_rescan_device(&sdev->sdev_gendev);
@@@ -540,7 -540,7 +540,7 @@@ static void storvsc_remove_lun(struct w
        if (!scsi_host_get(wrk->host))
                goto done;
  
-       sdev = scsi_device_lookup(wrk->host, 0, 0, wrk->lun);
+       sdev = scsi_device_lookup(wrk->host, 0, wrk->tgt_id, wrk->lun);
  
        if (sdev) {
                scsi_remove_device(sdev);
@@@ -940,6 -940,7 +940,7 @@@ static void storvsc_handle_error(struc
  
        wrk->host = host;
        wrk->lun = vm_srb->lun;
+       wrk->tgt_id = vm_srb->target_id;
        INIT_WORK(&wrk->work, process_err_fn);
        schedule_work(&wrk->work);
  }
@@@ -1770,6 -1771,11 +1771,11 @@@ static int __init storvsc_drv_init(void
        fc_transport_template = fc_attach_transport(&fc_transport_functions);
        if (!fc_transport_template)
                return -ENODEV;
+       /*
+        * Install Hyper-V specific timeout handler.
+        */
+       fc_transport_template->eh_timed_out = storvsc_eh_timed_out;
  #endif
  
        ret = vmbus_driver_register(&storvsc_drv);
diff --combined include/linux/blkdev.h
@@@ -409,7 -409,6 +409,7 @@@ struct request_queue 
  
        unsigned int            rq_timeout;
        struct timer_list       timeout;
 +      struct work_struct      timeout_work;
        struct list_head        timeout_list;
  
        struct list_head        icq_list;
@@@ -682,9 -681,12 +682,12 @@@ static inline bool blk_write_same_merge
  /*
   * q->prep_rq_fn return values
   */
- #define BLKPREP_OK            0       /* serve it */
- #define BLKPREP_KILL          1       /* fatal error, kill */
- #define BLKPREP_DEFER         2       /* leave on queue */
+ enum {
+       BLKPREP_OK,             /* serve it */
+       BLKPREP_KILL,           /* fatal error, kill, return -EIO */
+       BLKPREP_DEFER,          /* leave on queue */
+       BLKPREP_INVALID,        /* invalid command, kill, return -EREMOTEIO */
+ };
  
  extern unsigned long blk_max_low_pfn, blk_max_pfn;