kconfig.h: use already defined macros for IS_REACHABLE() define
[cascardo/linux.git] / drivers / ata / libata-scsi.c
index 7bcc870..bfec66f 100644 (file)
@@ -270,11 +270,52 @@ DEVICE_ATTR(unload_heads, S_IRUGO | S_IWUSR,
            ata_scsi_park_show, ata_scsi_park_store);
 EXPORT_SYMBOL_GPL(dev_attr_unload_heads);
 
-static void ata_scsi_set_sense(struct scsi_cmnd *cmd, u8 sk, u8 asc, u8 ascq)
+void ata_scsi_set_sense(struct ata_device *dev, struct scsi_cmnd *cmd,
+                       u8 sk, u8 asc, u8 ascq)
 {
+       bool d_sense = (dev->flags & ATA_DFLAG_D_SENSE);
+
+       if (!cmd)
+               return;
+
        cmd->result = (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION;
 
-       scsi_build_sense_buffer(0, cmd->sense_buffer, sk, asc, ascq);
+       scsi_build_sense_buffer(d_sense, cmd->sense_buffer, sk, asc, ascq);
+}
+
+void ata_scsi_set_sense_information(struct ata_device *dev,
+                                   struct scsi_cmnd *cmd,
+                                   const struct ata_taskfile *tf)
+{
+       u64 information;
+
+       if (!cmd)
+               return;
+
+       information = ata_tf_read_block(tf, dev);
+       if (information == U64_MAX)
+               return;
+
+       scsi_set_sense_information(cmd->sense_buffer,
+                                  SCSI_SENSE_BUFFERSIZE, information);
+}
+
+static void ata_scsi_set_invalid_field(struct ata_device *dev,
+                                      struct scsi_cmnd *cmd, u16 field, u8 bit)
+{
+       ata_scsi_set_sense(dev, cmd, ILLEGAL_REQUEST, 0x24, 0x0);
+       /* "Invalid field in cbd" */
+       scsi_set_sense_field_pointer(cmd->sense_buffer, SCSI_SENSE_BUFFERSIZE,
+                                    field, bit, 1);
+}
+
+static void ata_scsi_set_invalid_parameter(struct ata_device *dev,
+                                          struct scsi_cmnd *cmd, u16 field)
+{
+       /* "Invalid field in parameter list" */
+       ata_scsi_set_sense(dev, cmd, ILLEGAL_REQUEST, 0x26, 0x0);
+       scsi_set_sense_field_pointer(cmd->sense_buffer, SCSI_SENSE_BUFFERSIZE,
+                                    field, 0xff, 0);
 }
 
 static ssize_t
@@ -364,10 +405,10 @@ struct device_attribute *ata_common_sdev_attrs[] = {
 };
 EXPORT_SYMBOL_GPL(ata_common_sdev_attrs);
 
-static void ata_scsi_invalid_field(struct scsi_cmnd *cmd)
+static void ata_scsi_invalid_field(struct ata_device *dev,
+                                  struct scsi_cmnd *cmd, u16 field)
 {
-       ata_scsi_set_sense(cmd, ILLEGAL_REQUEST, 0x24, 0x0);
-       /* "Invalid field in cbd" */
+       ata_scsi_set_invalid_field(dev, cmd, field, 0xff);
        cmd->scsi_done(cmd);
 }
 
@@ -980,6 +1021,7 @@ static void ata_gen_passthru_sense(struct ata_queued_cmd *qc)
        unsigned char *sb = cmd->sense_buffer;
        unsigned char *desc = sb + 8;
        int verbose = qc->ap->ops->error_handler == NULL;
+       u8 sense_key, asc, ascq;
 
        memset(sb, 0, SCSI_SENSE_BUFFERSIZE);
 
@@ -992,47 +1034,71 @@ static void ata_gen_passthru_sense(struct ata_queued_cmd *qc)
        if (qc->err_mask ||
            tf->command & (ATA_BUSY | ATA_DF | ATA_ERR | ATA_DRQ)) {
                ata_to_sense_error(qc->ap->print_id, tf->command, tf->feature,
-                                  &sb[1], &sb[2], &sb[3], verbose);
-               sb[1] &= 0x0f;
+                                  &sense_key, &asc, &ascq, verbose);
+               ata_scsi_set_sense(qc->dev, cmd, sense_key, asc, ascq);
        } else {
-               sb[1] = RECOVERED_ERROR;
-               sb[2] = 0;
-               sb[3] = 0x1D;
+               /*
+                * ATA PASS-THROUGH INFORMATION AVAILABLE
+                * Always in descriptor format sense.
+                */
+               scsi_build_sense_buffer(1, cmd->sense_buffer,
+                                       RECOVERED_ERROR, 0, 0x1D);
        }
 
-       /*
-        * Sense data is current and format is descriptor.
-        */
-       sb[0] = 0x72;
-
-       desc[0] = 0x09;
-
-       /* set length of additional sense data */
-       sb[7] = 14;
-       desc[1] = 12;
-
-       /*
-        * Copy registers into sense buffer.
-        */
-       desc[2] = 0x00;
-       desc[3] = tf->feature;  /* == error reg */
-       desc[5] = tf->nsect;
-       desc[7] = tf->lbal;
-       desc[9] = tf->lbam;
-       desc[11] = tf->lbah;
-       desc[12] = tf->device;
-       desc[13] = tf->command; /* == status reg */
+       if ((cmd->sense_buffer[0] & 0x7f) >= 0x72) {
+               u8 len;
+
+               /* descriptor format */
+               len = sb[7];
+               desc = (char *)scsi_sense_desc_find(sb, len + 8, 9);
+               if (!desc) {
+                       if (SCSI_SENSE_BUFFERSIZE < len + 14)
+                               return;
+                       sb[7] = len + 14;
+                       desc = sb + 8 + len;
+               }
+               desc[0] = 9;
+               desc[1] = 12;
+               /*
+                * Copy registers into sense buffer.
+                */
+               desc[2] = 0x00;
+               desc[3] = tf->feature;  /* == error reg */
+               desc[5] = tf->nsect;
+               desc[7] = tf->lbal;
+               desc[9] = tf->lbam;
+               desc[11] = tf->lbah;
+               desc[12] = tf->device;
+               desc[13] = tf->command; /* == status reg */
 
-       /*
-        * Fill in Extend bit, and the high order bytes
-        * if applicable.
-        */
-       if (tf->flags & ATA_TFLAG_LBA48) {
-               desc[2] |= 0x01;
-               desc[4] = tf->hob_nsect;
-               desc[6] = tf->hob_lbal;
-               desc[8] = tf->hob_lbam;
-               desc[10] = tf->hob_lbah;
+               /*
+                * Fill in Extend bit, and the high order bytes
+                * if applicable.
+                */
+               if (tf->flags & ATA_TFLAG_LBA48) {
+                       desc[2] |= 0x01;
+                       desc[4] = tf->hob_nsect;
+                       desc[6] = tf->hob_lbal;
+                       desc[8] = tf->hob_lbam;
+                       desc[10] = tf->hob_lbah;
+               }
+       } else {
+               /* Fixed sense format */
+               desc[0] = tf->feature;
+               desc[1] = tf->command; /* status */
+               desc[2] = tf->device;
+               desc[3] = tf->nsect;
+               desc[0] = 0;
+               if (tf->flags & ATA_TFLAG_LBA48)  {
+                       desc[8] |= 0x80;
+                       if (tf->hob_nsect)
+                               desc[8] |= 0x40;
+                       if (tf->hob_lbal || tf->hob_lbam || tf->hob_lbah)
+                               desc[8] |= 0x20;
+               }
+               desc[9] = tf->lbal;
+               desc[10] = tf->lbam;
+               desc[11] = tf->lbah;
        }
 }
 
@@ -1052,41 +1118,41 @@ static void ata_gen_ata_sense(struct ata_queued_cmd *qc)
        struct scsi_cmnd *cmd = qc->scsicmd;
        struct ata_taskfile *tf = &qc->result_tf;
        unsigned char *sb = cmd->sense_buffer;
-       unsigned char *desc = sb + 8;
        int verbose = qc->ap->ops->error_handler == NULL;
        u64 block;
+       u8 sense_key, asc, ascq;
 
        memset(sb, 0, SCSI_SENSE_BUFFERSIZE);
 
        cmd->result = (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION;
 
-       /* sense data is current and format is descriptor */
-       sb[0] = 0x72;
-
+       if (ata_dev_disabled(dev)) {
+               /* Device disabled after error recovery */
+               /* LOGICAL UNIT NOT READY, HARD RESET REQUIRED */
+               ata_scsi_set_sense(dev, cmd, NOT_READY, 0x04, 0x21);
+               return;
+       }
        /* Use ata_to_sense_error() to map status register bits
         * onto sense key, asc & ascq.
         */
        if (qc->err_mask ||
            tf->command & (ATA_BUSY | ATA_DF | ATA_ERR | ATA_DRQ)) {
                ata_to_sense_error(qc->ap->print_id, tf->command, tf->feature,
-                                  &sb[1], &sb[2], &sb[3], verbose);
-               sb[1] &= 0x0f;
+                                  &sense_key, &asc, &ascq, verbose);
+               ata_scsi_set_sense(dev, cmd, sense_key, asc, ascq);
+       } else {
+               /* Could not decode error */
+               ata_dev_warn(dev, "could not decode error status 0x%x err_mask 0x%x\n",
+                            tf->command, qc->err_mask);
+               ata_scsi_set_sense(dev, cmd, ABORTED_COMMAND, 0, 0);
+               return;
        }
 
        block = ata_tf_read_block(&qc->result_tf, dev);
+       if (block == U64_MAX)
+               return;
 
-       /* information sense data descriptor */
-       sb[7] = 12;
-       desc[0] = 0x00;
-       desc[1] = 10;
-
-       desc[2] |= 0x80;        /* valid */
-       desc[6] = block >> 40;
-       desc[7] = block >> 32;
-       desc[8] = block >> 24;
-       desc[9] = block >> 16;
-       desc[10] = block >> 8;
-       desc[11] = block;
+       scsi_set_sense_information(sb, SCSI_SENSE_BUFFERSIZE, block);
 }
 
 static void ata_scsi_sdev_config(struct scsi_device *sdev)
@@ -1343,19 +1409,29 @@ static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc)
        struct scsi_cmnd *scmd = qc->scsicmd;
        struct ata_taskfile *tf = &qc->tf;
        const u8 *cdb = scmd->cmnd;
+       u16 fp;
+       u8 bp = 0xff;
 
-       if (scmd->cmd_len < 5)
+       if (scmd->cmd_len < 5) {
+               fp = 4;
                goto invalid_fld;
+       }
 
        tf->flags |= ATA_TFLAG_DEVICE | ATA_TFLAG_ISADDR;
        tf->protocol = ATA_PROT_NODATA;
        if (cdb[1] & 0x1) {
                ;       /* ignore IMMED bit, violates sat-r05 */
        }
-       if (cdb[4] & 0x2)
+       if (cdb[4] & 0x2) {
+               fp = 4;
+               bp = 1;
                goto invalid_fld;       /* LOEJ bit set not supported */
-       if (((cdb[4] >> 4) & 0xf) != 0)
+       }
+       if (((cdb[4] >> 4) & 0xf) != 0) {
+               fp = 4;
+               bp = 3;
                goto invalid_fld;       /* power conditions not supported */
+       }
 
        if (cdb[4] & 0x1) {
                tf->nsect = 1;  /* 1 sector, lba=0 */
@@ -1401,8 +1477,7 @@ static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc)
        return 0;
 
  invalid_fld:
-       ata_scsi_set_sense(scmd, ILLEGAL_REQUEST, 0x24, 0x0);
-       /* "Invalid field in cbd" */
+       ata_scsi_set_invalid_field(qc->dev, scmd, fp, bp);
        return 1;
  skip:
        scmd->result = SAM_STAT_GOOD;
@@ -1553,20 +1628,27 @@ static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc)
        const u8 *cdb = scmd->cmnd;
        u64 block;
        u32 n_block;
+       u16 fp;
 
        tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
        tf->protocol = ATA_PROT_NODATA;
 
        if (cdb[0] == VERIFY) {
-               if (scmd->cmd_len < 10)
+               if (scmd->cmd_len < 10) {
+                       fp = 9;
                        goto invalid_fld;
+               }
                scsi_10_lba_len(cdb, &block, &n_block);
        } else if (cdb[0] == VERIFY_16) {
-               if (scmd->cmd_len < 16)
+               if (scmd->cmd_len < 16) {
+                       fp = 15;
                        goto invalid_fld;
+               }
                scsi_16_lba_len(cdb, &block, &n_block);
-       } else
+       } else {
+               fp = 0;
                goto invalid_fld;
+       }
 
        if (!n_block)
                goto nothing_to_do;
@@ -1640,12 +1722,11 @@ static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc)
        return 0;
 
 invalid_fld:
-       ata_scsi_set_sense(scmd, ILLEGAL_REQUEST, 0x24, 0x0);
-       /* "Invalid field in cbd" */
+       ata_scsi_set_invalid_field(qc->dev, scmd, fp, 0xff);
        return 1;
 
 out_of_range:
-       ata_scsi_set_sense(scmd, ILLEGAL_REQUEST, 0x21, 0x0);
+       ata_scsi_set_sense(qc->dev, scmd, ILLEGAL_REQUEST, 0x21, 0x0);
        /* "Logical Block Address out of range" */
        return 1;
 
@@ -1680,6 +1761,7 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc)
        u64 block;
        u32 n_block;
        int rc;
+       u16 fp = 0;
 
        if (cdb[0] == WRITE_10 || cdb[0] == WRITE_6 || cdb[0] == WRITE_16)
                tf_flags |= ATA_TFLAG_WRITE;
@@ -1688,16 +1770,20 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc)
        switch (cdb[0]) {
        case READ_10:
        case WRITE_10:
-               if (unlikely(scmd->cmd_len < 10))
+               if (unlikely(scmd->cmd_len < 10)) {
+                       fp = 9;
                        goto invalid_fld;
+               }
                scsi_10_lba_len(cdb, &block, &n_block);
                if (cdb[1] & (1 << 3))
                        tf_flags |= ATA_TFLAG_FUA;
                break;
        case READ_6:
        case WRITE_6:
-               if (unlikely(scmd->cmd_len < 6))
+               if (unlikely(scmd->cmd_len < 6)) {
+                       fp = 5;
                        goto invalid_fld;
+               }
                scsi_6_lba_len(cdb, &block, &n_block);
 
                /* for 6-byte r/w commands, transfer length 0
@@ -1708,14 +1794,17 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc)
                break;
        case READ_16:
        case WRITE_16:
-               if (unlikely(scmd->cmd_len < 16))
+               if (unlikely(scmd->cmd_len < 16)) {
+                       fp = 15;
                        goto invalid_fld;
+               }
                scsi_16_lba_len(cdb, &block, &n_block);
                if (cdb[1] & (1 << 3))
                        tf_flags |= ATA_TFLAG_FUA;
                break;
        default:
                DPRINTK("no-byte command\n");
+               fp = 0;
                goto invalid_fld;
        }
 
@@ -1742,12 +1831,11 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc)
                goto out_of_range;
        /* treat all other errors as -EINVAL, fall through */
 invalid_fld:
-       ata_scsi_set_sense(scmd, ILLEGAL_REQUEST, 0x24, 0x0);
-       /* "Invalid field in cbd" */
+       ata_scsi_set_invalid_field(qc->dev, scmd, fp, 0xff);
        return 1;
 
 out_of_range:
-       ata_scsi_set_sense(scmd, ILLEGAL_REQUEST, 0x21, 0x0);
+       ata_scsi_set_sense(qc->dev, scmd, ILLEGAL_REQUEST, 0x21, 0x0);
        /* "Logical Block Address out of range" */
        return 1;
 
@@ -1784,6 +1872,8 @@ static void ata_scsi_qc_complete(struct ata_queued_cmd *qc)
        if (((cdb[0] == ATA_16) || (cdb[0] == ATA_12)) &&
            ((cdb[2] & 0x20) || need_sense))
                ata_gen_passthru_sense(qc);
+       else if (qc->flags & ATA_QCFLAG_SENSE_VALID)
+               cmd->result = SAM_STAT_CHECK_CONDITION;
        else if (need_sense)
                ata_gen_ata_sense(qc);
        else
@@ -1992,14 +2082,14 @@ static unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf)
                0x00,
                0xA0,   /* SAM-5 (no version claimed) */
 
-               0x04,
-               0xC0,   /* SBC-3 (no version claimed) */
+               0x06,
+               0x00,   /* SBC-4 (no version claimed) */
 
-               0x04,
-               0x60,   /* SPC-4 (no version claimed) */
+               0x05,
+               0xC0,   /* SPC-5 (no version claimed) */
 
                0x60,
-               0x20,   /* ZBC (no version claimed) */
+               0x24,   /* ZBC r05 */
        };
 
        u8 hdr[] = {
@@ -2019,10 +2109,8 @@ static unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf)
            (args->dev->link->ap->pflags & ATA_PFLAG_EXTERNAL))
                hdr[1] |= (1 << 7);
 
-       if (args->dev->class == ATA_DEV_ZAC) {
+       if (args->dev->class == ATA_DEV_ZAC)
                hdr[0] = TYPE_ZBC;
-               hdr[2] = 0x6; /* ZBC is defined in SPC-4 */
-       }
 
        memcpy(rbuf, hdr, sizeof(hdr));
        memcpy(&rbuf[8], "ATA     ", 8);
@@ -2036,7 +2124,7 @@ static unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf)
        if (rbuf[32] == 0 || rbuf[32] == ' ')
                memcpy(&rbuf[32], "n/a ", 4);
 
-       if (args->dev->class == ATA_DEV_ZAC)
+       if (ata_id_zoned_cap(args->id) || args->dev->class == ATA_DEV_ZAC)
                memcpy(rbuf + 58, versions_zbc, sizeof(versions_zbc));
        else
                memcpy(rbuf + 58, versions, sizeof(versions));
@@ -2056,6 +2144,7 @@ static unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf)
  */
 static unsigned int ata_scsiop_inq_00(struct ata_scsi_args *args, u8 *rbuf)
 {
+       int num_pages;
        const u8 pages[] = {
                0x00,   /* page 0x00, this page */
                0x80,   /* page 0x80, unit serial no page */
@@ -2064,10 +2153,14 @@ static unsigned int ata_scsiop_inq_00(struct ata_scsi_args *args, u8 *rbuf)
                0xb0,   /* page 0xb0, block limits page */
                0xb1,   /* page 0xb1, block device characteristics page */
                0xb2,   /* page 0xb2, thin provisioning page */
+               0xb6,   /* page 0xb6, zoned block device characteristics */
        };
 
-       rbuf[3] = sizeof(pages);        /* number of supported VPD pages */
-       memcpy(rbuf + 4, pages, sizeof(pages));
+       num_pages = sizeof(pages);
+       if (!(args->dev->flags & ATA_DFLAG_ZAC))
+               num_pages--;
+       rbuf[3] = num_pages;    /* number of supported VPD pages */
+       memcpy(rbuf + 4, pages, num_pages);
        return 0;
 }
 
@@ -2232,12 +2325,15 @@ static unsigned int ata_scsiop_inq_b1(struct ata_scsi_args *args, u8 *rbuf)
 {
        int form_factor = ata_id_form_factor(args->id);
        int media_rotation_rate = ata_id_rotation_rate(args->id);
+       u8 zoned = ata_id_zoned_cap(args->id);
 
        rbuf[1] = 0xb1;
        rbuf[3] = 0x3c;
        rbuf[4] = media_rotation_rate >> 8;
        rbuf[5] = media_rotation_rate;
        rbuf[7] = form_factor;
+       if (zoned)
+               rbuf[8] = (zoned << 4);
 
        return 0;
 }
@@ -2252,6 +2348,26 @@ static unsigned int ata_scsiop_inq_b2(struct ata_scsi_args *args, u8 *rbuf)
        return 0;
 }
 
+static unsigned int ata_scsiop_inq_b6(struct ata_scsi_args *args, u8 *rbuf)
+{
+       /*
+        * zbc-r05 SCSI Zoned Block device characteristics VPD page
+        */
+       rbuf[1] = 0xb6;
+       rbuf[3] = 0x3C;
+
+       /*
+        * URSWRZ bit is only meaningful for host-managed ZAC drives
+        */
+       if (args->dev->zac_zoned_cap & 1)
+               rbuf[4] |= 1;
+       put_unaligned_be32(args->dev->zac_zones_optimal_open, &rbuf[8]);
+       put_unaligned_be32(args->dev->zac_zones_optimal_nonseq, &rbuf[12]);
+       put_unaligned_be32(args->dev->zac_zones_max_open, &rbuf[16]);
+
+       return 0;
+}
+
 /**
  *     ata_scsiop_noop - Command handler that simply returns success.
  *     @args: device IDENTIFY data / SCSI command of interest.
@@ -2317,6 +2433,7 @@ static unsigned int ata_msense_caching(u16 *id, u8 *buf, bool changeable)
 
 /**
  *     ata_msense_ctl_mode - Simulate MODE SENSE control mode page
+ *     @dev: ATA device of interest
  *     @buf: output buffer
  *     @changeable: whether changeable parameters are requested
  *
@@ -2325,9 +2442,12 @@ static unsigned int ata_msense_caching(u16 *id, u8 *buf, bool changeable)
  *     LOCKING:
  *     None.
  */
-static unsigned int ata_msense_ctl_mode(u8 *buf, bool changeable)
+static unsigned int ata_msense_ctl_mode(struct ata_device *dev, u8 *buf,
+                                       bool changeable)
 {
        modecpy(buf, def_control_mpage, sizeof(def_control_mpage), changeable);
+       if (changeable && (dev->flags & ATA_DFLAG_D_SENSE))
+               buf[2] |= (1 << 2);     /* Descriptor sense requested */
        return sizeof(def_control_mpage);
 }
 
@@ -2395,7 +2515,8 @@ static unsigned int ata_scsiop_mode_sense(struct ata_scsi_args *args, u8 *rbuf)
        };
        u8 pg, spg;
        unsigned int ebd, page_control, six_byte;
-       u8 dpofua;
+       u8 dpofua, bp = 0xff;
+       u16 fp;
 
        VPRINTK("ENTER\n");
 
@@ -2414,6 +2535,8 @@ static unsigned int ata_scsiop_mode_sense(struct ata_scsi_args *args, u8 *rbuf)
        case 3: /* saved */
                goto saving_not_supp;
        default:
+               fp = 2;
+               bp = 6;
                goto invalid_fld;
        }
 
@@ -2428,8 +2551,10 @@ static unsigned int ata_scsiop_mode_sense(struct ata_scsi_args *args, u8 *rbuf)
         * No mode subpages supported (yet) but asking for _all_
         * subpages may be valid
         */
-       if (spg && (spg != ALL_SUB_MPAGES))
+       if (spg && (spg != ALL_SUB_MPAGES)) {
+               fp = 3;
                goto invalid_fld;
+       }
 
        switch(pg) {
        case RW_RECOVERY_MPAGE:
@@ -2441,16 +2566,17 @@ static unsigned int ata_scsiop_mode_sense(struct ata_scsi_args *args, u8 *rbuf)
                break;
 
        case CONTROL_MPAGE:
-               p += ata_msense_ctl_mode(p, page_control == 1);
+               p += ata_msense_ctl_mode(args->dev, p, page_control == 1);
                break;
 
        case ALL_MPAGES:
                p += ata_msense_rw_recovery(p, page_control == 1);
                p += ata_msense_caching(args->id, p, page_control == 1);
-               p += ata_msense_ctl_mode(p, page_control == 1);
+               p += ata_msense_ctl_mode(args->dev, p, page_control == 1);
                break;
 
        default:                /* invalid page code */
+               fp = 2;
                goto invalid_fld;
        }
 
@@ -2480,12 +2606,11 @@ static unsigned int ata_scsiop_mode_sense(struct ata_scsi_args *args, u8 *rbuf)
        return 0;
 
 invalid_fld:
-       ata_scsi_set_sense(args->cmd, ILLEGAL_REQUEST, 0x24, 0x0);
-       /* "Invalid field in cbd" */
+       ata_scsi_set_invalid_field(dev, args->cmd, fp, bp);
        return 1;
 
 saving_not_supp:
-       ata_scsi_set_sense(args->cmd, ILLEGAL_REQUEST, 0x39, 0x0);
+       ata_scsi_set_sense(dev, args->cmd, ILLEGAL_REQUEST, 0x39, 0x0);
         /* "Saving parameters not supported" */
        return 1;
 }
@@ -2561,6 +2686,9 @@ static unsigned int ata_scsiop_read_cap(struct ata_scsi_args *args, u8 *rbuf)
                                rbuf[14] |= 0x40; /* LBPRZ */
                        }
                }
+               if (ata_id_zoned_cap(args->id) ||
+                   args->dev->class == ATA_DEV_ZAC)
+                       rbuf[12] = (1 << 4); /* RC_BASIS */
        }
        return 0;
 }
@@ -2942,9 +3070,12 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc)
        struct scsi_cmnd *scmd = qc->scsicmd;
        struct ata_device *dev = qc->dev;
        const u8 *cdb = scmd->cmnd;
+       u16 fp;
 
-       if ((tf->protocol = ata_scsi_map_proto(cdb[1])) == ATA_PROT_UNKNOWN)
+       if ((tf->protocol = ata_scsi_map_proto(cdb[1])) == ATA_PROT_UNKNOWN) {
+               fp = 1;
                goto invalid_fld;
+       }
 
        /* enable LBA */
        tf->flags |= ATA_TFLAG_LBA;
@@ -3008,8 +3139,10 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc)
        case ATA_CMD_READ_LONG_ONCE:
        case ATA_CMD_WRITE_LONG:
        case ATA_CMD_WRITE_LONG_ONCE:
-               if (tf->protocol != ATA_PROT_PIO || tf->nsect != 1)
+               if (tf->protocol != ATA_PROT_PIO || tf->nsect != 1) {
+                       fp = 1;
                        goto invalid_fld;
+               }
                qc->sect_size = scsi_bufflen(scmd);
                break;
 
@@ -3072,12 +3205,16 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc)
        ata_qc_set_pc_nbytes(qc);
 
        /* We may not issue DMA commands if no DMA mode is set */
-       if (tf->protocol == ATA_PROT_DMA && dev->dma_mode == 0)
+       if (tf->protocol == ATA_PROT_DMA && dev->dma_mode == 0) {
+               fp = 1;
                goto invalid_fld;
+       }
 
        /* sanity check for pio multi commands */
-       if ((cdb[1] & 0xe0) && !is_multi_taskfile(tf))
+       if ((cdb[1] & 0xe0) && !is_multi_taskfile(tf)) {
+               fp = 1;
                goto invalid_fld;
+       }
 
        if (is_multi_taskfile(tf)) {
                unsigned int multi_count = 1 << (cdb[1] >> 5);
@@ -3098,8 +3235,10 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc)
         * ->set_dmamode(), and ->post_set_mode() hooks).
         */
        if (tf->command == ATA_CMD_SET_FEATURES &&
-           tf->feature == SETFEATURES_XFER)
+           tf->feature == SETFEATURES_XFER) {
+               fp = (cdb[0] == ATA_16) ? 4 : 3;
                goto invalid_fld;
+       }
 
        /*
         * Filter TPM commands by default. These provide an
@@ -3116,14 +3255,15 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc)
         * so that we comply with the TC consortium stated goal that the user
         * can turn off TC features of their system.
         */
-       if (tf->command >= 0x5C && tf->command <= 0x5F && !libata_allow_tpm)
+       if (tf->command >= 0x5C && tf->command <= 0x5F && !libata_allow_tpm) {
+               fp = (cdb[0] == ATA_16) ? 14 : 9;
                goto invalid_fld;
+       }
 
        return 0;
 
  invalid_fld:
-       ata_scsi_set_sense(scmd, ILLEGAL_REQUEST, 0x24, 0x00);
-       /* "Invalid field in cdb" */
+       ata_scsi_set_invalid_field(dev, scmd, fp, 0xff);
        return 1;
 }
 
@@ -3137,25 +3277,32 @@ static unsigned int ata_scsi_write_same_xlat(struct ata_queued_cmd *qc)
        u32 n_block;
        u32 size;
        void *buf;
+       u16 fp;
+       u8 bp = 0xff;
 
        /* we may not issue DMA commands if no DMA mode is set */
        if (unlikely(!dev->dma_mode))
-               goto invalid_fld;
+               goto invalid_opcode;
 
-       if (unlikely(scmd->cmd_len < 16))
+       if (unlikely(scmd->cmd_len < 16)) {
+               fp = 15;
                goto invalid_fld;
+       }
        scsi_16_lba_len(cdb, &block, &n_block);
 
        /* for now we only support WRITE SAME with the unmap bit set */
-       if (unlikely(!(cdb[1] & 0x8)))
+       if (unlikely(!(cdb[1] & 0x8))) {
+               fp = 1;
+               bp = 3;
                goto invalid_fld;
+       }
 
        /*
         * WRITE SAME always has a sector sized buffer as payload, this
         * should never be a multiple entry S/G list.
         */
        if (!scsi_sg_count(scmd))
-               goto invalid_fld;
+               goto invalid_param_len;
 
        buf = page_address(sg_page(scsi_sglist(scmd)));
        size = ata_set_lba_range_entries(buf, 512, block, n_block);
@@ -3186,9 +3333,242 @@ static unsigned int ata_scsi_write_same_xlat(struct ata_queued_cmd *qc)
 
        return 0;
 
+invalid_fld:
+       ata_scsi_set_invalid_field(dev, scmd, fp, bp);
+       return 1;
+invalid_param_len:
+       /* "Parameter list length error" */
+       ata_scsi_set_sense(dev, scmd, ILLEGAL_REQUEST, 0x1a, 0x0);
+       return 1;
+invalid_opcode:
+       /* "Invalid command operation code" */
+       ata_scsi_set_sense(dev, scmd, ILLEGAL_REQUEST, 0x20, 0x0);
+       return 1;
+}
+
+/**
+ *     ata_scsi_report_zones_complete - convert ATA output
+ *     @qc: command structure returning the data
+ *
+ *     Convert T-13 little-endian field representation into
+ *     T-10 big-endian field representation.
+ *     What a mess.
+ */
+static void ata_scsi_report_zones_complete(struct ata_queued_cmd *qc)
+{
+       struct scsi_cmnd *scmd = qc->scsicmd;
+       struct sg_mapping_iter miter;
+       unsigned long flags;
+       unsigned int bytes = 0;
+
+       sg_miter_start(&miter, scsi_sglist(scmd), scsi_sg_count(scmd),
+                      SG_MITER_TO_SG | SG_MITER_ATOMIC);
+
+       local_irq_save(flags);
+       while (sg_miter_next(&miter)) {
+               unsigned int offset = 0;
+
+               if (bytes == 0) {
+                       char *hdr;
+                       u32 list_length;
+                       u64 max_lba, opt_lba;
+                       u16 same;
+
+                       /* Swizzle header */
+                       hdr = miter.addr;
+                       list_length = get_unaligned_le32(&hdr[0]);
+                       same = get_unaligned_le16(&hdr[4]);
+                       max_lba = get_unaligned_le64(&hdr[8]);
+                       opt_lba = get_unaligned_le64(&hdr[16]);
+                       put_unaligned_be32(list_length, &hdr[0]);
+                       hdr[4] = same & 0xf;
+                       put_unaligned_be64(max_lba, &hdr[8]);
+                       put_unaligned_be64(opt_lba, &hdr[16]);
+                       offset += 64;
+                       bytes += 64;
+               }
+               while (offset < miter.length) {
+                       char *rec;
+                       u8 cond, type, non_seq, reset;
+                       u64 size, start, wp;
+
+                       /* Swizzle zone descriptor */
+                       rec = miter.addr + offset;
+                       type = rec[0] & 0xf;
+                       cond = (rec[1] >> 4) & 0xf;
+                       non_seq = (rec[1] & 2);
+                       reset = (rec[1] & 1);
+                       size = get_unaligned_le64(&rec[8]);
+                       start = get_unaligned_le64(&rec[16]);
+                       wp = get_unaligned_le64(&rec[24]);
+                       rec[0] = type;
+                       rec[1] = (cond << 4) | non_seq | reset;
+                       put_unaligned_be64(size, &rec[8]);
+                       put_unaligned_be64(start, &rec[16]);
+                       put_unaligned_be64(wp, &rec[24]);
+                       WARN_ON(offset + 64 > miter.length);
+                       offset += 64;
+                       bytes += 64;
+               }
+       }
+       sg_miter_stop(&miter);
+       local_irq_restore(flags);
+
+       ata_scsi_qc_complete(qc);
+}
+
+static unsigned int ata_scsi_zbc_in_xlat(struct ata_queued_cmd *qc)
+{
+       struct ata_taskfile *tf = &qc->tf;
+       struct scsi_cmnd *scmd = qc->scsicmd;
+       const u8 *cdb = scmd->cmnd;
+       u16 sect, fp = (u16)-1;
+       u8 sa, options, bp = 0xff;
+       u64 block;
+       u32 n_block;
+
+       if (unlikely(scmd->cmd_len < 16)) {
+               ata_dev_warn(qc->dev, "invalid cdb length %d\n",
+                            scmd->cmd_len);
+               fp = 15;
+               goto invalid_fld;
+       }
+       scsi_16_lba_len(cdb, &block, &n_block);
+       if (n_block != scsi_bufflen(scmd)) {
+               ata_dev_warn(qc->dev, "non-matching transfer count (%d/%d)\n",
+                            n_block, scsi_bufflen(scmd));
+               goto invalid_param_len;
+       }
+       sa = cdb[1] & 0x1f;
+       if (sa != ZI_REPORT_ZONES) {
+               ata_dev_warn(qc->dev, "invalid service action %d\n", sa);
+               fp = 1;
+               goto invalid_fld;
+       }
+       /*
+        * ZAC allows only for transfers in 512 byte blocks,
+        * and uses a 16 bit value for the transfer count.
+        */
+       if ((n_block / 512) > 0xffff || n_block < 512 || (n_block % 512)) {
+               ata_dev_warn(qc->dev, "invalid transfer count %d\n", n_block);
+               goto invalid_param_len;
+       }
+       sect = n_block / 512;
+       options = cdb[14];
+
+       if (ata_ncq_enabled(qc->dev) &&
+           ata_fpdma_zac_mgmt_in_supported(qc->dev)) {
+               tf->protocol = ATA_PROT_NCQ;
+               tf->command = ATA_CMD_FPDMA_RECV;
+               tf->hob_nsect = ATA_SUBCMD_FPDMA_RECV_ZAC_MGMT_IN & 0x1f;
+               tf->nsect = qc->tag << 3;
+               tf->feature = sect & 0xff;
+               tf->hob_feature = (sect >> 8) & 0xff;
+               tf->auxiliary = ATA_SUBCMD_ZAC_MGMT_IN_REPORT_ZONES;
+       } else {
+               tf->command = ATA_CMD_ZAC_MGMT_IN;
+               tf->feature = ATA_SUBCMD_ZAC_MGMT_IN_REPORT_ZONES;
+               tf->protocol = ATA_PROT_DMA;
+               tf->hob_feature = options;
+               tf->hob_nsect = (sect >> 8) & 0xff;
+               tf->nsect = sect & 0xff;
+       }
+       tf->device = ATA_LBA;
+       tf->lbah = (block >> 16) & 0xff;
+       tf->lbam = (block >> 8) & 0xff;
+       tf->lbal = block & 0xff;
+       tf->hob_lbah = (block >> 40) & 0xff;
+       tf->hob_lbam = (block >> 32) & 0xff;
+       tf->hob_lbal = (block >> 24) & 0xff;
+
+       tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE | ATA_TFLAG_LBA48;
+       qc->flags |= ATA_QCFLAG_RESULT_TF;
+
+       ata_qc_set_pc_nbytes(qc);
+
+       qc->complete_fn = ata_scsi_report_zones_complete;
+
+       return 0;
+
+invalid_fld:
+       ata_scsi_set_invalid_field(qc->dev, scmd, fp, bp);
+       return 1;
+
+invalid_param_len:
+       /* "Parameter list length error" */
+       ata_scsi_set_sense(qc->dev, scmd, ILLEGAL_REQUEST, 0x1a, 0x0);
+       return 1;
+}
+
+static unsigned int ata_scsi_zbc_out_xlat(struct ata_queued_cmd *qc)
+{
+       struct ata_taskfile *tf = &qc->tf;
+       struct scsi_cmnd *scmd = qc->scsicmd;
+       struct ata_device *dev = qc->dev;
+       const u8 *cdb = scmd->cmnd;
+       u8 reset_all, sa;
+       u64 block;
+       u32 n_block;
+       u16 fp = (u16)-1;
+
+       if (unlikely(scmd->cmd_len < 16)) {
+               fp = 15;
+               goto invalid_fld;
+       }
+
+       sa = cdb[1] & 0x1f;
+       if ((sa != ZO_CLOSE_ZONE) && (sa != ZO_FINISH_ZONE) &&
+           (sa != ZO_OPEN_ZONE) && (sa != ZO_RESET_WRITE_POINTER)) {
+               fp = 1;
+               goto invalid_fld;
+       }
+
+       scsi_16_lba_len(cdb, &block, &n_block);
+       if (n_block) {
+               /*
+                * ZAC MANAGEMENT OUT doesn't define any length
+                */
+               goto invalid_param_len;
+       }
+       if (block > dev->n_sectors)
+               goto out_of_range;
+
+       reset_all = cdb[14] & 0x1;
+
+       if (ata_ncq_enabled(qc->dev) &&
+           ata_fpdma_zac_mgmt_out_supported(qc->dev)) {
+               tf->protocol = ATA_PROT_NCQ;
+               tf->command = ATA_CMD_NCQ_NON_DATA;
+               tf->hob_nsect = ATA_SUBCMD_NCQ_NON_DATA_ZAC_MGMT_OUT;
+               tf->nsect = qc->tag << 3;
+               tf->auxiliary = sa | (reset_all & 0x1) << 8;
+       } else {
+               tf->protocol = ATA_PROT_NODATA;
+               tf->command = ATA_CMD_ZAC_MGMT_OUT;
+               tf->feature = sa;
+               tf->hob_feature = reset_all & 0x1;
+       }
+       tf->lbah = (block >> 16) & 0xff;
+       tf->lbam = (block >> 8) & 0xff;
+       tf->lbal = block & 0xff;
+       tf->hob_lbah = (block >> 40) & 0xff;
+       tf->hob_lbam = (block >> 32) & 0xff;
+       tf->hob_lbal = (block >> 24) & 0xff;
+       tf->device = ATA_LBA;
+       tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE | ATA_TFLAG_LBA48;
+
+       return 0;
+
  invalid_fld:
-       ata_scsi_set_sense(scmd, ILLEGAL_REQUEST, 0x24, 0x00);
-       /* "Invalid field in cdb" */
+       ata_scsi_set_invalid_field(qc->dev, scmd, fp, 0xff);
+       return 1;
+ out_of_range:
+       /* "Logical Block Address out of range" */
+       ata_scsi_set_sense(qc->dev, scmd, ILLEGAL_REQUEST, 0x21, 0x00);
+       return 1;
+invalid_param_len:
+       /* "Parameter list length error" */
+       ata_scsi_set_sense(qc->dev, scmd, ILLEGAL_REQUEST, 0x1a, 0x0);
        return 1;
 }
 
@@ -3197,6 +3577,7 @@ static unsigned int ata_scsi_write_same_xlat(struct ata_queued_cmd *qc)
  *     @qc: Storage for translated ATA taskfile
  *     @buf: input buffer
  *     @len: number of valid bytes in the input buffer
+ *     @fp: out parameter for the failed field on error
  *
  *     Prepare a taskfile to modify caching information for the device.
  *
@@ -3204,20 +3585,26 @@ static unsigned int ata_scsi_write_same_xlat(struct ata_queued_cmd *qc)
  *     None.
  */
 static int ata_mselect_caching(struct ata_queued_cmd *qc,
-                              const u8 *buf, int len)
+                              const u8 *buf, int len, u16 *fp)
 {
        struct ata_taskfile *tf = &qc->tf;
        struct ata_device *dev = qc->dev;
        char mpage[CACHE_MPAGE_LEN];
        u8 wce;
+       int i;
 
        /*
         * The first two bytes of def_cache_mpage are a header, so offsets
         * in mpage are off by 2 compared to buf.  Same for len.
         */
 
-       if (len != CACHE_MPAGE_LEN - 2)
+       if (len != CACHE_MPAGE_LEN - 2) {
+               if (len < CACHE_MPAGE_LEN - 2)
+                       *fp = len;
+               else
+                       *fp = CACHE_MPAGE_LEN - 2;
                return -EINVAL;
+       }
 
        wce = buf[0] & (1 << 2);
 
@@ -3225,10 +3612,14 @@ static int ata_mselect_caching(struct ata_queued_cmd *qc,
         * Check that read-only bits are not modified.
         */
        ata_msense_caching(dev->id, mpage, false);
-       mpage[2] &= ~(1 << 2);
-       mpage[2] |= wce;
-       if (memcmp(mpage + 2, buf, CACHE_MPAGE_LEN - 2) != 0)
-               return -EINVAL;
+       for (i = 0; i < CACHE_MPAGE_LEN - 2; i++) {
+               if (i == 0)
+                       continue;
+               if (mpage[i + 2] != buf[i]) {
+                       *fp = i;
+                       return -EINVAL;
+               }
+       }
 
        tf->flags |= ATA_TFLAG_DEVICE | ATA_TFLAG_ISADDR;
        tf->protocol = ATA_PROT_NODATA;
@@ -3238,6 +3629,62 @@ static int ata_mselect_caching(struct ata_queued_cmd *qc,
        return 0;
 }
 
+/**
+ *     ata_mselect_control - Simulate MODE SELECT for control page
+ *     @qc: Storage for translated ATA taskfile
+ *     @buf: input buffer
+ *     @len: number of valid bytes in the input buffer
+ *     @fp: out parameter for the failed field on error
+ *
+ *     Prepare a taskfile to modify caching information for the device.
+ *
+ *     LOCKING:
+ *     None.
+ */
+static int ata_mselect_control(struct ata_queued_cmd *qc,
+                              const u8 *buf, int len, u16 *fp)
+{
+       struct ata_device *dev = qc->dev;
+       char mpage[CONTROL_MPAGE_LEN];
+       u8 d_sense;
+       int i;
+
+       /*
+        * The first two bytes of def_control_mpage are a header, so offsets
+        * in mpage are off by 2 compared to buf.  Same for len.
+        */
+
+       if (len != CONTROL_MPAGE_LEN - 2) {
+               if (len < CONTROL_MPAGE_LEN - 2)
+                       *fp = len;
+               else
+                       *fp = CONTROL_MPAGE_LEN - 2;
+               return -EINVAL;
+       }
+
+       d_sense = buf[0] & (1 << 2);
+
+       /*
+        * Check that read-only bits are not modified.
+        */
+       ata_msense_ctl_mode(dev, mpage, false);
+       for (i = 0; i < CONTROL_MPAGE_LEN - 2; i++) {
+               if (i == 0)
+                       continue;
+               if (mpage[2 + i] != buf[i]) {
+                       *fp = i;
+                       return -EINVAL;
+               }
+       }
+       if (d_sense & (1 << 2))
+               dev->flags |= ATA_DFLAG_D_SENSE;
+       else
+               dev->flags &= ~ATA_DFLAG_D_SENSE;
+       qc->scsicmd->result = SAM_STAT_GOOD;
+       qc->scsicmd->scsi_done(qc->scsicmd);
+       return 0;
+}
+
 /**
  *     ata_scsiop_mode_select - Simulate MODE SELECT 6, 10 commands
  *     @qc: Storage for translated ATA taskfile
@@ -3257,27 +3704,36 @@ static unsigned int ata_scsi_mode_select_xlat(struct ata_queued_cmd *qc)
        u8 pg, spg;
        unsigned six_byte, pg_len, hdr_len, bd_len;
        int len;
+       u16 fp = (u16)-1;
+       u8 bp = 0xff;
 
        VPRINTK("ENTER\n");
 
        six_byte = (cdb[0] == MODE_SELECT);
        if (six_byte) {
-               if (scmd->cmd_len < 5)
+               if (scmd->cmd_len < 5) {
+                       fp = 4;
                        goto invalid_fld;
+               }
 
                len = cdb[4];
                hdr_len = 4;
        } else {
-               if (scmd->cmd_len < 9)
+               if (scmd->cmd_len < 9) {
+                       fp = 8;
                        goto invalid_fld;
+               }
 
                len = (cdb[7] << 8) + cdb[8];
                hdr_len = 8;
        }
 
        /* We only support PF=1, SP=0.  */
-       if ((cdb[1] & 0x11) != 0x10)
+       if ((cdb[1] & 0x11) != 0x10) {
+               fp = 1;
+               bp = (cdb[1] & 0x01) ? 1 : 5;
                goto invalid_fld;
+       }
 
        /* Test early for possible overrun.  */
        if (!scsi_sg_count(scmd) || scsi_sglist(scmd)->length < len)
@@ -3298,8 +3754,11 @@ static unsigned int ata_scsi_mode_select_xlat(struct ata_queued_cmd *qc)
        p += hdr_len;
        if (len < bd_len)
                goto invalid_param_len;
-       if (bd_len != 0 && bd_len != 8)
+       if (bd_len != 0 && bd_len != 8) {
+               fp = (six_byte) ? 3 : 6;
+               fp += bd_len + hdr_len;
                goto invalid_param;
+       }
 
        len -= bd_len;
        p += bd_len;
@@ -3330,18 +3789,29 @@ static unsigned int ata_scsi_mode_select_xlat(struct ata_queued_cmd *qc)
         * No mode subpages supported (yet) but asking for _all_
         * subpages may be valid
         */
-       if (spg && (spg != ALL_SUB_MPAGES))
+       if (spg && (spg != ALL_SUB_MPAGES)) {
+               fp = (p[0] & 0x40) ? 1 : 0;
+               fp += hdr_len + bd_len;
                goto invalid_param;
+       }
        if (pg_len > len)
                goto invalid_param_len;
 
        switch (pg) {
        case CACHE_MPAGE:
-               if (ata_mselect_caching(qc, p, pg_len) < 0)
+               if (ata_mselect_caching(qc, p, pg_len, &fp) < 0) {
+                       fp += hdr_len + bd_len;
                        goto invalid_param;
+               }
+               break;
+       case CONTROL_MPAGE:
+               if (ata_mselect_control(qc, p, pg_len, &fp) < 0) {
+                       fp += hdr_len + bd_len;
+                       goto invalid_param;
+               }
                break;
-
        default:                /* invalid page code */
+               fp = bd_len + hdr_len;
                goto invalid_param;
        }
 
@@ -3355,18 +3825,16 @@ static unsigned int ata_scsi_mode_select_xlat(struct ata_queued_cmd *qc)
        return 0;
 
  invalid_fld:
-       /* "Invalid field in CDB" */
-       ata_scsi_set_sense(scmd, ILLEGAL_REQUEST, 0x24, 0x0);
+       ata_scsi_set_invalid_field(qc->dev, scmd, fp, bp);
        return 1;
 
  invalid_param:
-       /* "Invalid field in parameter list" */
-       ata_scsi_set_sense(scmd, ILLEGAL_REQUEST, 0x26, 0x0);
+       ata_scsi_set_invalid_parameter(qc->dev, scmd, fp);
        return 1;
 
  invalid_param_len:
        /* "Parameter list length error" */
-       ata_scsi_set_sense(scmd, ILLEGAL_REQUEST, 0x1a, 0x0);
+       ata_scsi_set_sense(qc->dev, scmd, ILLEGAL_REQUEST, 0x1a, 0x0);
        return 1;
 
  skip:
@@ -3419,6 +3887,12 @@ static inline ata_xlat_func_t ata_get_xlat_func(struct ata_device *dev, u8 cmd)
                return ata_scsi_mode_select_xlat;
                break;
 
+       case ZBC_IN:
+               return ata_scsi_zbc_in_xlat;
+
+       case ZBC_OUT:
+               return ata_scsi_zbc_out_xlat;
+
        case START_STOP:
                return ata_scsi_start_stop_xlat;
        }
@@ -3567,12 +4041,12 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd)
        switch(scsicmd[0]) {
        /* TODO: worth improving? */
        case FORMAT_UNIT:
-               ata_scsi_invalid_field(cmd);
+               ata_scsi_invalid_field(dev, cmd, 0);
                break;
 
        case INQUIRY:
-               if (scsicmd[1] & 2)                /* is CmdDt set?  */
-                       ata_scsi_invalid_field(cmd);
+               if (scsicmd[1] & 2)                /* is CmdDt set?  */
+                   ata_scsi_invalid_field(dev, cmd, 1);
                else if ((scsicmd[1] & 1) == 0)    /* is EVPD clear? */
                        ata_scsi_rbuf_fill(&args, ata_scsiop_inq_std);
                else switch (scsicmd[2]) {
@@ -3597,8 +4071,14 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd)
                case 0xb2:
                        ata_scsi_rbuf_fill(&args, ata_scsiop_inq_b2);
                        break;
+               case 0xb6:
+                       if (dev->flags & ATA_DFLAG_ZAC) {
+                               ata_scsi_rbuf_fill(&args, ata_scsiop_inq_b6);
+                               break;
+                       }
+                       /* Fallthrough */
                default:
-                       ata_scsi_invalid_field(cmd);
+                       ata_scsi_invalid_field(dev, cmd, 2);
                        break;
                }
                break;
@@ -3616,7 +4096,7 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd)
                if ((scsicmd[1] & 0x1f) == SAI_READ_CAPACITY_16)
                        ata_scsi_rbuf_fill(&args, ata_scsiop_read_cap);
                else
-                       ata_scsi_invalid_field(cmd);
+                       ata_scsi_invalid_field(dev, cmd, 1);
                break;
 
        case REPORT_LUNS:
@@ -3624,7 +4104,7 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd)
                break;
 
        case REQUEST_SENSE:
-               ata_scsi_set_sense(cmd, 0, 0, 0);
+               ata_scsi_set_sense(dev, cmd, 0, 0, 0);
                cmd->result = (DRIVER_SENSE << 24);
                cmd->scsi_done(cmd);
                break;
@@ -3648,12 +4128,12 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd)
                if ((tmp8 == 0x4) && (!scsicmd[3]) && (!scsicmd[4]))
                        ata_scsi_rbuf_fill(&args, ata_scsiop_noop);
                else
-                       ata_scsi_invalid_field(cmd);
+                       ata_scsi_invalid_field(dev, cmd, 1);
                break;
 
        /* all other commands */
        default:
-               ata_scsi_set_sense(cmd, ILLEGAL_REQUEST, 0x20, 0x0);
+               ata_scsi_set_sense(dev, cmd, ILLEGAL_REQUEST, 0x20, 0x0);
                /* "Invalid command operation code" */
                cmd->scsi_done(cmd);
                break;