Merge tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 11 Feb 2015 18:28:45 +0000 (10:28 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 11 Feb 2015 18:28:45 +0000 (10:28 -0800)
Pull first round of SCSI updates from James Bottomley:
 "This is the usual grab bag of driver updates (hpsa, storvsc, mp2sas,
  megaraid_sas, ses) plus an assortment of minor updates.

  There's also an update to ufs which adds new phy drivers and finally a
  new logging infrastructure for SCSI"

* tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: (114 commits)
  scsi_logging: return void for dev_printk() functions
  scsi: print single-character strings with seq_putc
  scsi: merge consecutive seq_puts calls
  scsi: replace seq_printf with seq_puts
  aha152x: replace seq_printf with seq_puts
  advansys: replace seq_printf with seq_puts
  scsi: remove SPRINTF macro
  sg: remove an unused variable
  hpsa: Use local workqueues instead of system workqueues
  hpsa: add in P840ar controller model name
  hpsa: add in gen9 controller model names
  hpsa: detect and report failures changing controller transport modes
  hpsa: shorten the wait for the CISS doorbell mode change ack
  hpsa: refactor duplicated scan completion code into a new routine
  hpsa: move SG descriptor set-up out of hpsa_scatter_gather()
  hpsa: do not use function pointers in fast path command submission
  hpsa: print CDBs instead of kernel virtual addresses for uncommon errors
  hpsa: do not use a void pointer for scsi_cmd field of struct CommandList
  hpsa: return failed from device reset/abort handlers
  hpsa: check for ctlr lockup after command allocation in main io path
  ...

1  2 
drivers/ata/libata-eh.c
drivers/scsi/scsi.c
drivers/scsi/scsi_debug.c
drivers/scsi/sd.c
drivers/xen/xen-scsiback.c

diff --combined drivers/ata/libata-eh.c
@@@ -1635,6 -1635,7 +1635,6 @@@ unsigned int atapi_eh_request_sense(str
  
        DPRINTK("ATAPI request sense\n");
  
 -      /* FIXME: is this needed? */
        memset(sense_buf, 0, SCSI_SENSE_BUFFERSIZE);
  
        /* initialize sense_buf with the error register,
@@@ -2388,7 -2389,6 +2388,7 @@@ const char *ata_get_cmd_descript(u8 com
  
        return NULL;
  }
 +EXPORT_SYMBOL_GPL(ata_get_cmd_descript);
  
  /**
   *    ata_eh_link_report - report error handling to user
@@@ -2481,7 -2481,6 +2481,6 @@@ static void ata_eh_link_report(struct a
        for (tag = 0; tag < ATA_MAX_QUEUE; tag++) {
                struct ata_queued_cmd *qc = __ata_qc_from_tag(ap, tag);
                struct ata_taskfile *cmd = &qc->tf, *res = &qc->result_tf;
-               const u8 *cdb = qc->cdb;
                char data_buf[20] = "";
                char cdb_buf[70] = "";
  
                }
  
                if (ata_is_atapi(qc->tf.protocol)) {
-                       if (qc->scsicmd)
-                               scsi_print_command(qc->scsicmd);
-                       else
-                               snprintf(cdb_buf, sizeof(cdb_buf),
-                                "cdb %02x %02x %02x %02x %02x %02x %02x %02x  "
-                                "%02x %02x %02x %02x %02x %02x %02x %02x\n         ",
-                                cdb[0], cdb[1], cdb[2], cdb[3],
-                                cdb[4], cdb[5], cdb[6], cdb[7],
-                                cdb[8], cdb[9], cdb[10], cdb[11],
-                                cdb[12], cdb[13], cdb[14], cdb[15]);
+                       const u8 *cdb = qc->cdb;
+                       size_t cdb_len = qc->dev->cdb_len;
+                       if (qc->scsicmd) {
+                               cdb = qc->scsicmd->cmnd;
+                               cdb_len = qc->scsicmd->cmd_len;
+                       }
+                       __scsi_format_command(cdb_buf, sizeof(cdb_buf),
+                                             cdb, cdb_len);
                } else {
                        const char *descr = ata_get_cmd_descript(cmd->command);
                        if (descr)
diff --combined drivers/scsi/scsi.c
@@@ -531,7 -531,7 +531,7 @@@ void scsi_log_send(struct scsi_cmnd *cm
         *
         * 3: same as 2
         *
-        * 4: same as 3 plus dump extra junk
+        * 4: same as 3
         */
        if (unlikely(scsi_logging_level)) {
                level = SCSI_LOG_LEVEL(SCSI_LOG_MLQUEUE_SHIFT,
                        scmd_printk(KERN_INFO, cmd,
                                    "Send: scmd 0x%p\n", cmd);
                        scsi_print_command(cmd);
-                       if (level > 3) {
-                               printk(KERN_INFO "buffer = 0x%p, bufflen = %d,"
-                                      " queuecommand 0x%p\n",
-                                       scsi_sglist(cmd), scsi_bufflen(cmd),
-                                       cmd->device->host->hostt->queuecommand);
-                       }
                }
        }
  }
@@@ -572,7 -565,7 +565,7 @@@ void scsi_log_completion(struct scsi_cm
                                       SCSI_LOG_MLCOMPLETE_BITS);
                if (((level > 0) && (cmd->result || disposition != SUCCESS)) ||
                    (level > 1)) {
-                       scsi_print_result(cmd, "Done", disposition);
+                       scsi_print_result(cmd, "Done", disposition);
                        scsi_print_command(cmd);
                        if (status_byte(cmd->result) & CHECK_CONDITION)
                                scsi_print_sense(cmd);
@@@ -986,9 -979,9 +979,9 @@@ int scsi_device_get(struct scsi_device 
                return -ENXIO;
        if (!get_device(&sdev->sdev_gendev))
                return -ENXIO;
 -      /* We can fail this if we're doing SCSI operations
 +      /* We can fail try_module_get if we're doing SCSI operations
         * from module exit (like cache flush) */
 -      try_module_get(sdev->host->hostt->module);
 +      __module_get(sdev->host->hostt->module);
  
        return 0;
  }
@@@ -1004,7 -997,14 +997,7 @@@ EXPORT_SYMBOL(scsi_device_get)
   */
  void scsi_device_put(struct scsi_device *sdev)
  {
 -#ifdef CONFIG_MODULE_UNLOAD
 -      struct module *module = sdev->host->hostt->module;
 -
 -      /* The module refcount will be zero if scsi_device_get()
 -       * was called from a module removal routine */
 -      if (module && module_refcount(module) != 0)
 -              module_put(module);
 -#endif
 +      module_put(sdev->host->hostt->module);
        put_device(&sdev->sdev_gendev);
  }
  EXPORT_SYMBOL(scsi_device_put);
@@@ -80,6 -80,8 +80,8 @@@ static const char *scsi_debug_version_d
  #define INVALID_FIELD_IN_PARAM_LIST 0x26
  #define UA_RESET_ASC 0x29
  #define UA_CHANGED_ASC 0x2a
+ #define TARGET_CHANGED_ASC 0x3f
+ #define LUNS_CHANGED_ASCQ 0x0e
  #define INSUFF_RES_ASC 0x55
  #define INSUFF_RES_ASCQ 0x3
  #define POWER_ON_RESET_ASCQ 0x0
@@@ -91,6 -93,8 +93,8 @@@
  #define THRESHOLD_EXCEEDED 0x5d
  #define LOW_POWER_COND_ON 0x5e
  #define MISCOMPARE_VERIFY_ASC 0x1d
+ #define MICROCODE_CHANGED_ASCQ 0x1    /* with TARGET_CHANGED_ASC */
+ #define MICROCODE_CHANGED_WO_RESET_ASCQ 0x16
  
  /* Additional Sense Code Qualifier (ASCQ) */
  #define ACK_NAK_TO 0x3
  #define SDEBUG_UA_BUS_RESET 1
  #define SDEBUG_UA_MODE_CHANGED 2
  #define SDEBUG_UA_CAPACITY_CHANGED 3
- #define SDEBUG_NUM_UAS 4
+ #define SDEBUG_UA_LUNS_CHANGED 4
+ #define SDEBUG_UA_MICROCODE_CHANGED 5 /* simulate firmware change */
+ #define SDEBUG_UA_MICROCODE_CHANGED_WO_RESET 6
+ #define SDEBUG_NUM_UAS 7
  
  /* for check_readiness() */
  #define UAS_ONLY 1    /* check for UAs only */
@@@ -326,6 -333,7 +333,7 @@@ static int resp_write_same_10(struct sc
  static int resp_write_same_16(struct scsi_cmnd *, struct sdebug_dev_info *);
  static int resp_xdwriteread_10(struct scsi_cmnd *, struct sdebug_dev_info *);
  static int resp_comp_write(struct scsi_cmnd *, struct sdebug_dev_info *);
+ static int resp_write_buffer(struct scsi_cmnd *, struct sdebug_dev_info *);
  
  struct opcode_info_t {
        u8 num_attached;        /* 0 if this is it (i.e. a leaf); use 0xff
@@@ -480,8 -488,9 +488,9 @@@ static const struct opcode_info_t opcod
        {0, 0x53, 0, F_D_IN | F_D_OUT | FF_DIRECT_IO, resp_xdwriteread_10,
            NULL, {10,  0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0xff, 0xff, 0xc7,
                   0, 0, 0, 0, 0, 0} },
-       {0, 0, 0, F_INV_OP | FF_RESPOND, NULL, NULL, /* WRITE_BUFFER */
-           {0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
+       {0, 0x3b, 0, F_D_OUT_MAYBE, resp_write_buffer, NULL,
+           {10,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc7, 0, 0,
+            0, 0, 0, 0} },                     /* WRITE_BUFFER */
        {1, 0x41, 0, F_D_OUT_MAYBE | FF_DIRECT_IO, resp_write_same_10,
            write_same_iarr, {10,  0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0xff,
                              0xff, 0xc7, 0, 0, 0, 0, 0, 0} },
@@@ -782,6 -791,22 +791,22 @@@ static int scsi_debug_ioctl(struct scsi
        /* return -ENOTTY; // correct return but upsets fdisk */
  }
  
+ static void clear_luns_changed_on_target(struct sdebug_dev_info *devip)
+ {
+       struct sdebug_host_info *sdhp;
+       struct sdebug_dev_info *dp;
+       spin_lock(&sdebug_host_list_lock);
+       list_for_each_entry(sdhp, &sdebug_host_list, host_list) {
+               list_for_each_entry(dp, &sdhp->dev_info_list, dev_list) {
+                       if ((devip->sdbg_host == dp->sdbg_host) &&
+                           (devip->target == dp->target))
+                               clear_bit(SDEBUG_UA_LUNS_CHANGED, dp->uas_bm);
+               }
+       }
+       spin_unlock(&sdebug_host_list_lock);
+ }
  static int check_readiness(struct scsi_cmnd *SCpnt, int uas_only,
                           struct sdebug_dev_info * devip)
  {
                        if (debug)
                                cp = "capacity data changed";
                        break;
+               case SDEBUG_UA_MICROCODE_CHANGED:
+                       mk_sense_buffer(SCpnt, UNIT_ATTENTION,
+                                TARGET_CHANGED_ASC, MICROCODE_CHANGED_ASCQ);
+                       if (debug)
+                               cp = "microcode has been changed";
+                       break;
+               case SDEBUG_UA_MICROCODE_CHANGED_WO_RESET:
+                       mk_sense_buffer(SCpnt, UNIT_ATTENTION,
+                                       TARGET_CHANGED_ASC,
+                                       MICROCODE_CHANGED_WO_RESET_ASCQ);
+                       if (debug)
+                               cp = "microcode has been changed without reset";
+                       break;
+               case SDEBUG_UA_LUNS_CHANGED:
+                       /*
+                        * SPC-3 behavior is to report a UNIT ATTENTION with
+                        * ASC/ASCQ REPORTED LUNS DATA HAS CHANGED on every LUN
+                        * on the target, until a REPORT LUNS command is
+                        * received.  SPC-4 behavior is to report it only once.
+                        * NOTE:  scsi_debug_scsi_level does not use the same
+                        * values as struct scsi_device->scsi_level.
+                        */
+                       if (scsi_debug_scsi_level >= 6) /* SPC-4 and above */
+                               clear_luns_changed_on_target(devip);
+                       mk_sense_buffer(SCpnt, UNIT_ATTENTION,
+                                       TARGET_CHANGED_ASC,
+                                       LUNS_CHANGED_ASCQ);
+                       if (debug)
+                               cp = "reported luns data has changed";
+                       break;
                default:
                        pr_warn("%s: unexpected unit attention code=%d\n",
                                __func__, k);
@@@ -1623,7 -1678,7 +1678,7 @@@ resp_rsup_opcodes(struct scsi_cmnd *scp
        req_opcode = cmd[3];
        req_sa = get_unaligned_be16(cmd + 4);
        alloc_len = get_unaligned_be32(cmd + 6);
 -      if (alloc_len < 4 && alloc_len > 0xffff) {
 +      if (alloc_len < 4 || alloc_len > 0xffff) {
                mk_sense_invalid_fld(scp, SDEB_IN_CDB, 6, -1);
                return check_condition_result;
        }
                a_len = 8192;
        else
                a_len = alloc_len;
 -      arr = kzalloc((a_len < 256) ? 320 : a_len + 64, GFP_KERNEL);
 +      arr = kzalloc((a_len < 256) ? 320 : a_len + 64, GFP_ATOMIC);
        if (NULL == arr) {
                mk_sense_buffer(scp, ILLEGAL_REQUEST, INSUFF_RES_ASC,
                                INSUFF_RES_ASCQ);
@@@ -3033,6 -3088,55 +3088,55 @@@ resp_write_same_16(struct scsi_cmnd *sc
        return resp_write_same(scp, lba, num, ei_lba, unmap, ndob);
  }
  
+ /* Note the mode field is in the same position as the (lower) service action
+  * field. For the Report supported operation codes command, SPC-4 suggests
+  * each mode of this command should be reported separately; for future. */
+ static int
+ resp_write_buffer(struct scsi_cmnd *scp, struct sdebug_dev_info *devip)
+ {
+       u8 *cmd = scp->cmnd;
+       struct scsi_device *sdp = scp->device;
+       struct sdebug_dev_info *dp;
+       u8 mode;
+       mode = cmd[1] & 0x1f;
+       switch (mode) {
+       case 0x4:       /* download microcode (MC) and activate (ACT) */
+               /* set UAs on this device only */
+               set_bit(SDEBUG_UA_BUS_RESET, devip->uas_bm);
+               set_bit(SDEBUG_UA_MICROCODE_CHANGED, devip->uas_bm);
+               break;
+       case 0x5:       /* download MC, save and ACT */
+               set_bit(SDEBUG_UA_MICROCODE_CHANGED_WO_RESET, devip->uas_bm);
+               break;
+       case 0x6:       /* download MC with offsets and ACT */
+               /* set UAs on most devices (LUs) in this target */
+               list_for_each_entry(dp,
+                                   &devip->sdbg_host->dev_info_list,
+                                   dev_list)
+                       if (dp->target == sdp->id) {
+                               set_bit(SDEBUG_UA_BUS_RESET, dp->uas_bm);
+                               if (devip != dp)
+                                       set_bit(SDEBUG_UA_MICROCODE_CHANGED,
+                                               dp->uas_bm);
+                       }
+               break;
+       case 0x7:       /* download MC with offsets, save, and ACT */
+               /* set UA on all devices (LUs) in this target */
+               list_for_each_entry(dp,
+                                   &devip->sdbg_host->dev_info_list,
+                                   dev_list)
+                       if (dp->target == sdp->id)
+                               set_bit(SDEBUG_UA_MICROCODE_CHANGED_WO_RESET,
+                                       dp->uas_bm);
+               break;
+       default:
+               /* do nothing for this command for other mode values */
+               break;
+       }
+       return 0;
+ }
  static int
  resp_comp_write(struct scsi_cmnd *scp, struct sdebug_dev_info *devip)
  {
@@@ -3229,6 -3333,7 +3333,7 @@@ static int resp_report_luns(struct scsi
        unsigned char arr[SDEBUG_RLUN_ARR_SZ];
        unsigned char * max_addr;
  
+       clear_luns_changed_on_target(devip);
        alloc_len = cmd[9] + (cmd[8] << 8) + (cmd[7] << 16) + (cmd[6] << 24);
        shortish = (alloc_len < 4);
        if (shortish || (select_report > 2)) {
@@@ -4369,10 -4474,27 +4474,27 @@@ static ssize_t max_luns_store(struct de
                              size_t count)
  {
          int n;
+       bool changed;
  
        if ((count > 0) && (1 == sscanf(buf, "%d", &n)) && (n >= 0)) {
+               changed = (scsi_debug_max_luns != n);
                scsi_debug_max_luns = n;
                sdebug_max_tgts_luns();
+               if (changed && (scsi_debug_scsi_level >= 5)) {  /* >= SPC-3 */
+                       struct sdebug_host_info *sdhp;
+                       struct sdebug_dev_info *dp;
+                       spin_lock(&sdebug_host_list_lock);
+                       list_for_each_entry(sdhp, &sdebug_host_list,
+                                           host_list) {
+                               list_for_each_entry(dp, &sdhp->dev_info_list,
+                                                   dev_list) {
+                                       set_bit(SDEBUG_UA_LUNS_CHANGED,
+                                               dp->uas_bm);
+                               }
+                       }
+                       spin_unlock(&sdebug_host_list_lock);
+               }
                return count;
        }
        return -EINVAL;
diff --combined drivers/scsi/sd.c
@@@ -2800,11 -2800,9 +2800,11 @@@ static int sd_revalidate_disk(struct ge
         */
        sd_set_flush_flag(sdkp);
  
 -      max_xfer = min_not_zero(queue_max_hw_sectors(sdkp->disk->queue),
 -                              sdkp->max_xfer_blocks);
 +      max_xfer = sdkp->max_xfer_blocks;
        max_xfer <<= ilog2(sdp->sector_size) - 9;
 +
 +      max_xfer = min_not_zero(queue_max_hw_sectors(sdkp->disk->queue),
 +                              max_xfer);
        blk_queue_max_hw_sectors(sdkp->disk->queue, max_xfer);
        set_capacity(disk, sdkp->capacity);
        sd_config_write_same(sdkp);
@@@ -3320,11 -3318,8 +3320,8 @@@ module_exit(exit_sd)
  static void sd_print_sense_hdr(struct scsi_disk *sdkp,
                               struct scsi_sense_hdr *sshdr)
  {
-       scsi_show_sense_hdr(sdkp->device,
-                           sdkp->disk ? sdkp->disk->disk_name : NULL, sshdr);
-       scsi_show_extd_sense(sdkp->device,
-                            sdkp->disk ? sdkp->disk->disk_name : NULL,
-                            sshdr->asc, sshdr->ascq);
+       scsi_print_sense_hdr(sdkp->device,
+                            sdkp->disk ? sdkp->disk->disk_name : NULL, sshdr);
  }
  
  static void sd_print_result(const struct scsi_disk *sdkp, const char *msg,
@@@ -47,6 -47,7 +47,7 @@@
  
  #include <generated/utsrelease.h>
  
+ #include <scsi/scsi.h>
  #include <scsi/scsi_dbg.h>
  #include <scsi/scsi_eh.h>
  #include <scsi/scsi_tcq.h>
@@@ -227,7 -228,7 +228,7 @@@ static void put_free_pages(struct page 
                return;
        if (i > scsiback_max_buffer_pages) {
                n = min(num, i - scsiback_max_buffer_pages);
 -              free_xenballooned_pages(n, page + num - n);
 +              gnttab_free_pages(n, page + num - n);
                n = num - n;
        }
        spin_lock_irqsave(&free_pages_lock, flags);
@@@ -244,7 -245,7 +245,7 @@@ static int get_free_page(struct page **
        spin_lock_irqsave(&free_pages_lock, flags);
        if (list_empty(&scsiback_free_pages)) {
                spin_unlock_irqrestore(&free_pages_lock, flags);
 -              return alloc_xenballooned_pages(1, page, false);
 +              return gnttab_alloc_pages(1, page);
        }
        page[0] = list_first_entry(&scsiback_free_pages, struct page, lru);
        list_del(&page[0]->lru);
@@@ -2106,7 -2107,7 +2107,7 @@@ static void __exit scsiback_exit(void
        while (free_pages_num) {
                if (get_free_page(&page))
                        BUG();
 -              free_xenballooned_pages(1, &page);
 +              gnttab_free_pages(1, &page);
        }
        scsiback_deregister_configfs();
        xenbus_unregister_driver(&scsiback_driver);