summaryrefslogtreecommitdiffstats
path: root/drivers/scsi/libata-scsi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/libata-scsi.c')
-rw-r--r--drivers/scsi/libata-scsi.c45
1 files changed, 26 insertions, 19 deletions
diff --git a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c
index 3b4ca55a..e0439be 100644
--- a/drivers/scsi/libata-scsi.c
+++ b/drivers/scsi/libata-scsi.c
@@ -418,7 +418,7 @@ void ata_to_sense_error(unsigned id, u8 drv_stat, u8 drv_err, u8 *sk, u8 *asc,
int i;
/* Based on the 3ware driver translation table */
- static unsigned char sense_table[][4] = {
+ static const unsigned char sense_table[][4] = {
/* BBD|ECC|ID|MAR */
{0xd1, ABORTED_COMMAND, 0x00, 0x00}, // Device busy Aborted command
/* BBD|ECC|ID */
@@ -449,7 +449,7 @@ void ata_to_sense_error(unsigned id, u8 drv_stat, u8 drv_err, u8 *sk, u8 *asc,
{0x80, MEDIUM_ERROR, 0x11, 0x04}, // Block marked bad Medium error, unrecovered read error
{0xFF, 0xFF, 0xFF, 0xFF}, // END mark
};
- static unsigned char stat_table[][4] = {
+ static const unsigned char stat_table[][4] = {
/* Must be first because BUSY means no other bits valid */
{0x80, ABORTED_COMMAND, 0x47, 0x00}, // Busy, fake parity for now
{0x20, HARDWARE_ERROR, 0x00, 0x00}, // Device fault
@@ -1203,12 +1203,11 @@ nothing_to_do:
return 1;
}
-static int ata_scsi_qc_complete(struct ata_queued_cmd *qc,
- unsigned int err_mask)
+static int ata_scsi_qc_complete(struct ata_queued_cmd *qc)
{
struct scsi_cmnd *cmd = qc->scsicmd;
u8 *cdb = cmd->cmnd;
- int need_sense = (err_mask != 0);
+ int need_sense = (qc->err_mask != 0);
/* For ATA pass thru (SAT) commands, generate a sense block if
* user mandated it or if there's an error. Note that if we
@@ -1532,7 +1531,7 @@ unsigned int ata_scsiop_inq_80(struct ata_scsi_args *args, u8 *rbuf,
return 0;
}
-static const char *inq_83_str = "Linux ATA-SCSI simulator";
+static const char * const inq_83_str = "Linux ATA-SCSI simulator";
/**
* ata_scsiop_inq_83 - Simulate INQUIRY EVPD page 83, device identity
@@ -1955,9 +1954,9 @@ void ata_scsi_badcmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *), u8
done(cmd);
}
-static int atapi_sense_complete(struct ata_queued_cmd *qc,unsigned int err_mask)
+static int atapi_sense_complete(struct ata_queued_cmd *qc)
{
- if (err_mask && ((err_mask & AC_ERR_DEV) == 0))
+ if (qc->err_mask && ((qc->err_mask & AC_ERR_DEV) == 0))
/* FIXME: not quite right; we don't want the
* translation of taskfile registers into
* a sense descriptors, since that's only
@@ -2015,15 +2014,18 @@ static void atapi_request_sense(struct ata_queued_cmd *qc)
qc->complete_fn = atapi_sense_complete;
- if (ata_qc_issue(qc))
- ata_qc_complete(qc, AC_ERR_OTHER);
+ if (ata_qc_issue(qc)) {
+ qc->err_mask |= AC_ERR_OTHER;
+ ata_qc_complete(qc);
+ }
DPRINTK("EXIT\n");
}
-static int atapi_qc_complete(struct ata_queued_cmd *qc, unsigned int err_mask)
+static int atapi_qc_complete(struct ata_queued_cmd *qc)
{
struct scsi_cmnd *cmd = qc->scsicmd;
+ unsigned int err_mask = qc->err_mask;
VPRINTK("ENTER, err_mask 0x%X\n", err_mask);
@@ -2044,7 +2046,7 @@ static int atapi_qc_complete(struct ata_queued_cmd *qc, unsigned int err_mask)
else {
u8 *scsicmd = cmd->cmnd;
- if (scsicmd[0] == INQUIRY) {
+ if ((scsicmd[0] == INQUIRY) && ((scsicmd[1] & 0x03) == 0)) {
u8 *buf = NULL;
unsigned int buflen;
@@ -2058,9 +2060,6 @@ static int atapi_qc_complete(struct ata_queued_cmd *qc, unsigned int err_mask)
* device. 2) Ensure response data format / ATAPI information
* are always correct.
*/
- /* FIXME: do we ever override EVPD pages and the like, with
- * this code?
- */
if (buf[2] == 0) {
buf[2] = 0x5;
buf[3] = 0x32;
@@ -2173,9 +2172,12 @@ ata_scsi_find_dev(struct ata_port *ap, const struct scsi_device *scsidev)
if (unlikely(!ata_dev_present(dev)))
return NULL;
- if (!atapi_enabled) {
- if (unlikely(dev->class == ATA_DEV_ATAPI))
+ if (!atapi_enabled || (ap->flags & ATA_FLAG_NO_ATAPI)) {
+ if (unlikely(dev->class == ATA_DEV_ATAPI)) {
+ printk(KERN_WARNING "ata%u(%u): WARNING: ATAPI is %s, device ignored.\n",
+ ap->id, dev->devno, atapi_enabled ? "not supported with this driver" : "disabled");
return NULL;
+ }
}
return dev;
@@ -2239,7 +2241,7 @@ ata_scsi_pass_thru(struct ata_queued_cmd *qc, const u8 *scsicmd)
struct scsi_cmnd *cmd = qc->scsicmd;
if ((tf->protocol = ata_scsi_map_proto(scsicmd[1])) == ATA_PROT_UNKNOWN)
- return 1;
+ goto invalid_fld;
/*
* 12 and 16 byte CDBs use different offsets to
@@ -2301,7 +2303,7 @@ ata_scsi_pass_thru(struct ata_queued_cmd *qc, const u8 *scsicmd)
*/
if ((tf->command == ATA_CMD_SET_FEATURES)
&& (tf->feature == SETFEATURES_XFER))
- return 1;
+ goto invalid_fld;
/*
* Set flags so that all registers will be written,
@@ -2322,6 +2324,11 @@ ata_scsi_pass_thru(struct ata_queued_cmd *qc, const u8 *scsicmd)
qc->nsect = cmd->bufflen / ATA_SECT_SIZE;
return 0;
+
+ invalid_fld:
+ ata_scsi_set_sense(qc->scsicmd, ILLEGAL_REQUEST, 0x24, 0x00);
+ /* "Invalid field in cdb" */
+ return 1;
}
/**
OpenPOWER on IntegriCloud