]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/blobdiff - drivers/scsi/sd.c
block: better op and flags encoding
[mirror_ubuntu-zesty-kernel.git] / drivers / scsi / sd.c
index d3e852ad5aa34458b01f0979e629cd5009075861..65738b0aad367d1e0c3f850b8d5f7d019bbbfa0f 100644 (file)
@@ -52,6 +52,7 @@
 #include <linux/slab.h>
 #include <linux/pm_runtime.h>
 #include <linux/pr.h>
+#include <linux/t10-pi.h>
 #include <asm/uaccess.h>
 #include <asm/unaligned.h>
 
@@ -92,6 +93,7 @@ MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK15_MAJOR);
 MODULE_ALIAS_SCSI_DEVICE(TYPE_DISK);
 MODULE_ALIAS_SCSI_DEVICE(TYPE_MOD);
 MODULE_ALIAS_SCSI_DEVICE(TYPE_RBC);
+MODULE_ALIAS_SCSI_DEVICE(TYPE_ZBC);
 
 #if !defined(CONFIG_DEBUG_BLOCK_EXT_DEVT)
 #define SD_MINORS      16
@@ -162,7 +164,7 @@ cache_type_store(struct device *dev, struct device_attribute *attr,
        static const char temp[] = "temporary ";
        int len;
 
-       if (sdp->type != TYPE_DISK)
+       if (sdp->type != TYPE_DISK && sdp->type != TYPE_ZBC)
                /* no cache control on RBC devices; theoretically they
                 * can do it, but there's probably so many exceptions
                 * it's not worth the risk */
@@ -261,7 +263,7 @@ allow_restart_store(struct device *dev, struct device_attribute *attr,
        if (!capable(CAP_SYS_ADMIN))
                return -EACCES;
 
-       if (sdp->type != TYPE_DISK)
+       if (sdp->type != TYPE_DISK && sdp->type != TYPE_ZBC)
                return -EINVAL;
 
        sdp->allow_restart = simple_strtoul(buf, NULL, 10);
@@ -314,7 +316,7 @@ protection_type_store(struct device *dev, struct device_attribute *attr,
        if (err)
                return err;
 
-       if (val >= 0 && val <= SD_DIF_TYPE3_PROTECTION)
+       if (val >= 0 && val <= T10_PI_TYPE3_PROTECTION)
                sdkp->protection_type = val;
 
        return count;
@@ -332,7 +334,7 @@ protection_mode_show(struct device *dev, struct device_attribute *attr,
        dif = scsi_host_dif_capable(sdp->host, sdkp->protection_type);
        dix = scsi_host_dix_capable(sdp->host, sdkp->protection_type);
 
-       if (!dix && scsi_host_dix_capable(sdp->host, SD_DIF_TYPE0_PROTECTION)) {
+       if (!dix && scsi_host_dix_capable(sdp->host, T10_PI_TYPE0_PROTECTION)) {
                dif = 0;
                dix = 1;
        }
@@ -391,6 +393,11 @@ provisioning_mode_store(struct device *dev, struct device_attribute *attr,
        if (!capable(CAP_SYS_ADMIN))
                return -EACCES;
 
+       if (sd_is_zoned(sdkp)) {
+               sd_config_discard(sdkp, SD_LBP_DISABLE);
+               return count;
+       }
+
        if (sdp->type != TYPE_DISK)
                return -EINVAL;
 
@@ -458,7 +465,7 @@ max_write_same_blocks_store(struct device *dev, struct device_attribute *attr,
        if (!capable(CAP_SYS_ADMIN))
                return -EACCES;
 
-       if (sdp->type != TYPE_DISK)
+       if (sdp->type != TYPE_DISK && sdp->type != TYPE_ZBC)
                return -EINVAL;
 
        err = kstrtoul(buf, 10, &max);
@@ -608,7 +615,7 @@ static unsigned char sd_setup_protect_cmnd(struct scsi_cmnd *scmd,
                        scmd->prot_flags |= SCSI_PROT_GUARD_CHECK;
        }
 
-       if (dif != SD_DIF_TYPE3_PROTECTION) {   /* DIX/DIF Type 0, 1, 2 */
+       if (dif != T10_PI_TYPE3_PROTECTION) {   /* DIX/DIF Type 0, 1, 2 */
                scmd->prot_flags |= SCSI_PROT_REF_INCREMENT;
 
                if (bio_integrity_flagged(bio, BIP_CTRL_NOCHECK) == false)
@@ -843,6 +850,12 @@ static int sd_setup_write_same_cmnd(struct scsi_cmnd *cmd)
 
        BUG_ON(bio_offset(bio) || bio_iovec(bio).bv_len != sdp->sector_size);
 
+       if (sd_is_zoned(sdkp)) {
+               ret = sd_zbc_setup_write_cmnd(cmd);
+               if (ret != BLKPREP_OK)
+                       return ret;
+       }
+
        sector >>= ilog2(sdp->sector_size) - 9;
        nr_sectors >>= ilog2(sdp->sector_size) - 9;
 
@@ -900,19 +913,25 @@ static int sd_setup_read_write_cmnd(struct scsi_cmnd *SCpnt)
        struct request *rq = SCpnt->request;
        struct scsi_device *sdp = SCpnt->device;
        struct gendisk *disk = rq->rq_disk;
-       struct scsi_disk *sdkp;
+       struct scsi_disk *sdkp = scsi_disk(disk);
        sector_t block = blk_rq_pos(rq);
        sector_t threshold;
        unsigned int this_count = blk_rq_sectors(rq);
        unsigned int dif, dix;
+       bool zoned_write = sd_is_zoned(sdkp) && rq_data_dir(rq) == WRITE;
        int ret;
        unsigned char protect;
 
+       if (zoned_write) {
+               ret = sd_zbc_setup_write_cmnd(SCpnt);
+               if (ret != BLKPREP_OK)
+                       return ret;
+       }
+
        ret = scsi_init_io(SCpnt);
        if (ret != BLKPREP_OK)
                goto out;
        SCpnt = rq->special;
-       sdkp = scsi_disk(disk);
 
        /* from here on until we're complete, any goto out
         * is used for a killable error condition */
@@ -1012,8 +1031,7 @@ static int sd_setup_read_write_cmnd(struct scsi_cmnd *SCpnt)
        } else if (rq_data_dir(rq) == READ) {
                SCpnt->cmnd[0] = READ_6;
        } else {
-               scmd_printk(KERN_ERR, SCpnt, "Unknown command %llu,%llx\n",
-                           req_op(rq), (unsigned long long) rq->cmd_flags);
+               scmd_printk(KERN_ERR, SCpnt, "Unknown command %d\n", req_op(rq));
                goto out;
        }
 
@@ -1031,7 +1049,7 @@ static int sd_setup_read_write_cmnd(struct scsi_cmnd *SCpnt)
        else
                protect = 0;
 
-       if (protect && sdkp->protection_type == SD_DIF_TYPE2_PROTECTION) {
+       if (protect && sdkp->protection_type == T10_PI_TYPE2_PROTECTION) {
                SCpnt->cmnd = mempool_alloc(sd_cdb_pool, GFP_ATOMIC);
 
                if (unlikely(SCpnt->cmnd == NULL)) {
@@ -1131,6 +1149,9 @@ static int sd_setup_read_write_cmnd(struct scsi_cmnd *SCpnt)
         */
        ret = BLKPREP_OK;
  out:
+       if (zoned_write && ret != BLKPREP_OK)
+               sd_zbc_cancel_write_cmnd(SCpnt);
+
        return ret;
 }
 
@@ -1148,6 +1169,10 @@ static int sd_init_command(struct scsi_cmnd *cmd)
        case REQ_OP_READ:
        case REQ_OP_WRITE:
                return sd_setup_read_write_cmnd(cmd);
+       case REQ_OP_ZONE_REPORT:
+               return sd_zbc_setup_report_cmnd(cmd);
+       case REQ_OP_ZONE_RESET:
+               return sd_zbc_setup_reset_cmnd(cmd);
        default:
                BUG();
        }
@@ -1494,7 +1519,7 @@ static int sd_sync_cache(struct scsi_disk *sdkp)
                 */
                res = scsi_execute_req_flags(sdp, cmd, DMA_NONE, NULL, 0,
                                             &sshdr, timeout, SD_MAX_RETRIES,
-                                            NULL, REQ_PM);
+                                            NULL, 0, RQF_PM);
                if (res == 0)
                        break;
        }
@@ -1779,7 +1804,10 @@ static int sd_done(struct scsi_cmnd *SCpnt)
        unsigned char op = SCpnt->cmnd[0];
        unsigned char unmap = SCpnt->cmnd[1] & 8;
 
-       if (req_op(req) == REQ_OP_DISCARD || req_op(req) == REQ_OP_WRITE_SAME) {
+       switch (req_op(req)) {
+       case REQ_OP_DISCARD:
+       case REQ_OP_WRITE_SAME:
+       case REQ_OP_ZONE_RESET:
                if (!result) {
                        good_bytes = blk_rq_bytes(req);
                        scsi_set_resid(SCpnt, 0);
@@ -1787,6 +1815,17 @@ static int sd_done(struct scsi_cmnd *SCpnt)
                        good_bytes = 0;
                        scsi_set_resid(SCpnt, blk_rq_bytes(req));
                }
+               break;
+       case REQ_OP_ZONE_REPORT:
+               if (!result) {
+                       good_bytes = scsi_bufflen(SCpnt)
+                               - scsi_get_resid(SCpnt);
+                       scsi_set_resid(SCpnt, 0);
+               } else {
+                       good_bytes = 0;
+                       scsi_set_resid(SCpnt, blk_rq_bytes(req));
+               }
+               break;
        }
 
        if (result) {
@@ -1839,7 +1878,7 @@ static int sd_done(struct scsi_cmnd *SCpnt)
 
                                        good_bytes = 0;
                                        req->__data_len = blk_rq_bytes(req);
-                                       req->cmd_flags |= REQ_QUIET;
+                                       req->rq_flags |= RQF_QUIET;
                                }
                        }
                }
@@ -1847,7 +1886,11 @@ static int sd_done(struct scsi_cmnd *SCpnt)
        default:
                break;
        }
+
  out:
+       if (sd_is_zoned(sdkp))
+               sd_zbc_complete(SCpnt, good_bytes, &sshdr);
+
        SCSI_LOG_HLCOMPLETE(1, scmd_printk(KERN_INFO, SCpnt,
                                           "sd_done: completed %d of %d bytes\n",
                                           good_bytes, scsi_bufflen(SCpnt)));
@@ -1982,7 +2025,6 @@ sd_spinup_disk(struct scsi_disk *sdkp)
        }
 }
 
-
 /*
  * Determine whether disk supports Data Integrity Field.
  */
@@ -1997,7 +2039,7 @@ static int sd_read_protection_type(struct scsi_disk *sdkp, unsigned char *buffer
 
        type = ((buffer[12] >> 1) & 7) + 1; /* P_TYPE 0 = Type 1 */
 
-       if (type > SD_DIF_TYPE3_PROTECTION)
+       if (type > T10_PI_TYPE3_PROTECTION)
                ret = -ENODEV;
        else if (scsi_host_dif_capable(sdp->host, type))
                ret = 1;
@@ -2132,6 +2174,9 @@ static int read_capacity_16(struct scsi_disk *sdkp, struct scsi_device *sdp,
        /* Logical blocks per physical block exponent */
        sdkp->physical_block_size = (1 << (buffer[13] & 0xf)) * sector_size;
 
+       /* RC basis */
+       sdkp->rc_basis = (buffer[12] >> 4) & 0x3;
+
        /* Lowest aligned logical block */
        alignment = ((buffer[14] & 0x3f) << 8 | buffer[15]) * sector_size;
        blk_queue_alignment_offset(sdp->request_queue, alignment);
@@ -2241,7 +2286,6 @@ sd_read_capacity(struct scsi_disk *sdkp, unsigned char *buffer)
 {
        int sector_size;
        struct scsi_device *sdp = sdkp->device;
-       sector_t old_capacity = sdkp->capacity;
 
        if (sd_try_rc16_first(sdp)) {
                sector_size = read_capacity_16(sdkp, sdp, buffer);
@@ -2322,35 +2366,44 @@ got_data:
                sector_size = 512;
        }
        blk_queue_logical_block_size(sdp->request_queue, sector_size);
+       blk_queue_physical_block_size(sdp->request_queue,
+                                     sdkp->physical_block_size);
+       sdkp->device->sector_size = sector_size;
 
-       {
-               char cap_str_2[10], cap_str_10[10];
+       if (sdkp->capacity > 0xffffffff)
+               sdp->use_16_for_rw = 1;
 
-               string_get_size(sdkp->capacity, sector_size,
-                               STRING_UNITS_2, cap_str_2, sizeof(cap_str_2));
-               string_get_size(sdkp->capacity, sector_size,
-                               STRING_UNITS_10, cap_str_10,
-                               sizeof(cap_str_10));
+}
 
-               if (sdkp->first_scan || old_capacity != sdkp->capacity) {
-                       sd_printk(KERN_NOTICE, sdkp,
-                                 "%llu %d-byte logical blocks: (%s/%s)\n",
-                                 (unsigned long long)sdkp->capacity,
-                                 sector_size, cap_str_10, cap_str_2);
+/*
+ * Print disk capacity
+ */
+static void
+sd_print_capacity(struct scsi_disk *sdkp,
+                 sector_t old_capacity)
+{
+       int sector_size = sdkp->device->sector_size;
+       char cap_str_2[10], cap_str_10[10];
 
-                       if (sdkp->physical_block_size != sector_size)
-                               sd_printk(KERN_NOTICE, sdkp,
-                                         "%u-byte physical blocks\n",
-                                         sdkp->physical_block_size);
-               }
-       }
+       string_get_size(sdkp->capacity, sector_size,
+                       STRING_UNITS_2, cap_str_2, sizeof(cap_str_2));
+       string_get_size(sdkp->capacity, sector_size,
+                       STRING_UNITS_10, cap_str_10,
+                       sizeof(cap_str_10));
 
-       if (sdkp->capacity > 0xffffffff)
-               sdp->use_16_for_rw = 1;
+       if (sdkp->first_scan || old_capacity != sdkp->capacity) {
+               sd_printk(KERN_NOTICE, sdkp,
+                         "%llu %d-byte logical blocks: (%s/%s)\n",
+                         (unsigned long long)sdkp->capacity,
+                         sector_size, cap_str_10, cap_str_2);
 
-       blk_queue_physical_block_size(sdp->request_queue,
-                                     sdkp->physical_block_size);
-       sdkp->device->sector_size = sector_size;
+               if (sdkp->physical_block_size != sector_size)
+                       sd_printk(KERN_NOTICE, sdkp,
+                                 "%u-byte physical blocks\n",
+                                 sdkp->physical_block_size);
+
+               sd_zbc_print_zones(sdkp);
+       }
 }
 
 /* called with buffer of length 512 */
@@ -2612,7 +2665,7 @@ static void sd_read_app_tag_own(struct scsi_disk *sdkp, unsigned char *buffer)
        struct scsi_mode_data data;
        struct scsi_sense_hdr sshdr;
 
-       if (sdp->type != TYPE_DISK)
+       if (sdp->type != TYPE_DISK && sdp->type != TYPE_ZBC)
                return;
 
        if (sdkp->protection_type == 0)
@@ -2719,6 +2772,7 @@ static void sd_read_block_limits(struct scsi_disk *sdkp)
  */
 static void sd_read_block_characteristics(struct scsi_disk *sdkp)
 {
+       struct request_queue *q = sdkp->disk->queue;
        unsigned char *buffer;
        u16 rot;
        const int vpd_len = 64;
@@ -2733,10 +2787,21 @@ static void sd_read_block_characteristics(struct scsi_disk *sdkp)
        rot = get_unaligned_be16(&buffer[4]);
 
        if (rot == 1) {
-               queue_flag_set_unlocked(QUEUE_FLAG_NONROT, sdkp->disk->queue);
-               queue_flag_clear_unlocked(QUEUE_FLAG_ADD_RANDOM, sdkp->disk->queue);
+               queue_flag_set_unlocked(QUEUE_FLAG_NONROT, q);
+               queue_flag_clear_unlocked(QUEUE_FLAG_ADD_RANDOM, q);
        }
 
+       sdkp->zoned = (buffer[8] >> 4) & 3;
+       if (sdkp->zoned == 1)
+               q->limits.zoned = BLK_ZONED_HA;
+       else if (sdkp->device->type == TYPE_ZBC)
+               q->limits.zoned = BLK_ZONED_HM;
+       else
+               q->limits.zoned = BLK_ZONED_NONE;
+       if (blk_queue_is_zoned(q) && sdkp->first_scan)
+               sd_printk(KERN_NOTICE, sdkp, "Host-%s zoned block device\n",
+                     q->limits.zoned == BLK_ZONED_HM ? "managed" : "aware");
+
  out:
        kfree(buffer);
 }
@@ -2808,6 +2873,7 @@ static int sd_revalidate_disk(struct gendisk *disk)
        struct scsi_disk *sdkp = scsi_disk(disk);
        struct scsi_device *sdp = sdkp->device;
        struct request_queue *q = sdkp->disk->queue;
+       sector_t old_capacity = sdkp->capacity;
        unsigned char *buffer;
        unsigned int dev_max, rw_max;
 
@@ -2841,8 +2907,11 @@ static int sd_revalidate_disk(struct gendisk *disk)
                        sd_read_block_provisioning(sdkp);
                        sd_read_block_limits(sdkp);
                        sd_read_block_characteristics(sdkp);
+                       sd_zbc_read_zones(sdkp, buffer);
                }
 
+               sd_print_capacity(sdkp, old_capacity);
+
                sd_read_write_protect_flag(sdkp, buffer);
                sd_read_cache_type(sdkp, buffer);
                sd_read_app_tag_own(sdkp, buffer);
@@ -3040,9 +3109,16 @@ static int sd_probe(struct device *dev)
 
        scsi_autopm_get_device(sdp);
        error = -ENODEV;
-       if (sdp->type != TYPE_DISK && sdp->type != TYPE_MOD && sdp->type != TYPE_RBC)
+       if (sdp->type != TYPE_DISK &&
+           sdp->type != TYPE_ZBC &&
+           sdp->type != TYPE_MOD &&
+           sdp->type != TYPE_RBC)
                goto out;
 
+#ifndef CONFIG_BLK_DEV_ZONED
+       if (sdp->type == TYPE_ZBC)
+               goto out;
+#endif
        SCSI_LOG_HLQUEUE(3, sdev_printk(KERN_INFO, sdp,
                                        "sd_probe\n"));
 
@@ -3146,6 +3222,8 @@ static int sd_remove(struct device *dev)
        del_gendisk(sdkp->disk);
        sd_shutdown(dev);
 
+       sd_zbc_remove(sdkp);
+
        blk_register_region(devt, SD_MINORS, NULL,
                            sd_default_probe, NULL, NULL);
 
@@ -3199,7 +3277,7 @@ static int sd_start_stop_device(struct scsi_disk *sdkp, int start)
                return -ENODEV;
 
        res = scsi_execute_req_flags(sdp, cmd, DMA_NONE, NULL, 0, &sshdr,
-                              SD_TIMEOUT, SD_MAX_RETRIES, NULL, REQ_PM);
+                              SD_TIMEOUT, SD_MAX_RETRIES, NULL, 0, RQF_PM);
        if (res) {
                sd_print_result(sdkp, "Start/Stop Unit failed", res);
                if (driver_byte(res) & DRIVER_SENSE)