mirror of
https://github.com/FEX-Emu/linux.git
synced 2025-01-17 23:15:52 +00:00
libata: Implement control mode page to select sense format
Implement MODE SELECT for the control mode page to allow the OS to switch to descriptor sense. tj: Dropped s/sb/cmd->sense_buffer/ in ata_gen_ata_sense(). Added @dev description to ata_msense_ctl_mode(). Signed-off-by: Hannes Reinecke <hare@suse.de> Signed-off-by: Tejun Heo <tj@kernel.org>
This commit is contained in:
parent
11093cb1ef
commit
06dbde5f3a
@ -1679,7 +1679,7 @@ static void ata_eh_request_sense(struct ata_queued_cmd *qc,
|
|||||||
err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0, 0);
|
err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0, 0);
|
||||||
/* Ignore err_mask; ATA_ERR might be set */
|
/* Ignore err_mask; ATA_ERR might be set */
|
||||||
if (tf.command & ATA_SENSE) {
|
if (tf.command & ATA_SENSE) {
|
||||||
ata_scsi_set_sense(cmd, tf.lbah, tf.lbam, tf.lbal);
|
ata_scsi_set_sense(dev, cmd, tf.lbah, tf.lbam, tf.lbal);
|
||||||
qc->flags |= ATA_QCFLAG_SENSE_VALID;
|
qc->flags |= ATA_QCFLAG_SENSE_VALID;
|
||||||
} else {
|
} else {
|
||||||
ata_dev_warn(dev, "request sense failed stat %02x emask %x\n",
|
ata_dev_warn(dev, "request sense failed stat %02x emask %x\n",
|
||||||
@ -1855,7 +1855,7 @@ void ata_eh_analyze_ncq_error(struct ata_link *link)
|
|||||||
sense_key = (qc->result_tf.auxiliary >> 16) & 0xff;
|
sense_key = (qc->result_tf.auxiliary >> 16) & 0xff;
|
||||||
asc = (qc->result_tf.auxiliary >> 8) & 0xff;
|
asc = (qc->result_tf.auxiliary >> 8) & 0xff;
|
||||||
ascq = qc->result_tf.auxiliary & 0xff;
|
ascq = qc->result_tf.auxiliary & 0xff;
|
||||||
ata_scsi_set_sense(qc->scsicmd, sense_key, asc, ascq);
|
ata_scsi_set_sense(dev, qc->scsicmd, sense_key, asc, ascq);
|
||||||
ata_scsi_set_sense_information(dev, qc->scsicmd,
|
ata_scsi_set_sense_information(dev, qc->scsicmd,
|
||||||
&qc->result_tf);
|
&qc->result_tf);
|
||||||
qc->flags |= ATA_QCFLAG_SENSE_VALID;
|
qc->flags |= ATA_QCFLAG_SENSE_VALID;
|
||||||
|
@ -270,14 +270,17 @@ DEVICE_ATTR(unload_heads, S_IRUGO | S_IWUSR,
|
|||||||
ata_scsi_park_show, ata_scsi_park_store);
|
ata_scsi_park_show, ata_scsi_park_store);
|
||||||
EXPORT_SYMBOL_GPL(dev_attr_unload_heads);
|
EXPORT_SYMBOL_GPL(dev_attr_unload_heads);
|
||||||
|
|
||||||
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)
|
if (!cmd)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
cmd->result = (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION;
|
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,
|
void ata_scsi_set_sense_information(struct ata_device *dev,
|
||||||
@ -384,9 +387,10 @@ struct device_attribute *ata_common_sdev_attrs[] = {
|
|||||||
};
|
};
|
||||||
EXPORT_SYMBOL_GPL(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)
|
||||||
{
|
{
|
||||||
ata_scsi_set_sense(cmd, ILLEGAL_REQUEST, 0x24, 0x0);
|
ata_scsi_set_sense(dev, cmd, ILLEGAL_REQUEST, 0x24, 0x0);
|
||||||
/* "Invalid field in cbd" */
|
/* "Invalid field in cbd" */
|
||||||
cmd->scsi_done(cmd);
|
cmd->scsi_done(cmd);
|
||||||
}
|
}
|
||||||
@ -1014,7 +1018,7 @@ static void ata_gen_passthru_sense(struct ata_queued_cmd *qc)
|
|||||||
tf->command & (ATA_BUSY | ATA_DF | ATA_ERR | ATA_DRQ)) {
|
tf->command & (ATA_BUSY | ATA_DF | ATA_ERR | ATA_DRQ)) {
|
||||||
ata_to_sense_error(qc->ap->print_id, tf->command, tf->feature,
|
ata_to_sense_error(qc->ap->print_id, tf->command, tf->feature,
|
||||||
&sense_key, &asc, &ascq, verbose);
|
&sense_key, &asc, &ascq, verbose);
|
||||||
ata_scsi_set_sense(cmd, sense_key, asc, ascq);
|
ata_scsi_set_sense(qc->dev, cmd, sense_key, asc, ascq);
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
* ATA PASS-THROUGH INFORMATION AVAILABLE
|
* ATA PASS-THROUGH INFORMATION AVAILABLE
|
||||||
@ -1112,12 +1116,12 @@ static void ata_gen_ata_sense(struct ata_queued_cmd *qc)
|
|||||||
tf->command & (ATA_BUSY | ATA_DF | ATA_ERR | ATA_DRQ)) {
|
tf->command & (ATA_BUSY | ATA_DF | ATA_ERR | ATA_DRQ)) {
|
||||||
ata_to_sense_error(qc->ap->print_id, tf->command, tf->feature,
|
ata_to_sense_error(qc->ap->print_id, tf->command, tf->feature,
|
||||||
&sense_key, &asc, &ascq, verbose);
|
&sense_key, &asc, &ascq, verbose);
|
||||||
ata_scsi_set_sense(cmd, sense_key, asc, ascq);
|
ata_scsi_set_sense(dev, cmd, sense_key, asc, ascq);
|
||||||
} else {
|
} else {
|
||||||
/* Could not decode error */
|
/* Could not decode error */
|
||||||
ata_dev_warn(dev, "could not decode error status 0x%x err_mask 0x%x\n",
|
ata_dev_warn(dev, "could not decode error status 0x%x err_mask 0x%x\n",
|
||||||
tf->command, qc->err_mask);
|
tf->command, qc->err_mask);
|
||||||
ata_scsi_set_sense(cmd, ABORTED_COMMAND, 0, 0);
|
ata_scsi_set_sense(dev, cmd, ABORTED_COMMAND, 0, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1440,7 +1444,7 @@ static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
invalid_fld:
|
invalid_fld:
|
||||||
ata_scsi_set_sense(scmd, ILLEGAL_REQUEST, 0x24, 0x0);
|
ata_scsi_set_sense(qc->dev, scmd, ILLEGAL_REQUEST, 0x24, 0x0);
|
||||||
/* "Invalid field in cbd" */
|
/* "Invalid field in cbd" */
|
||||||
return 1;
|
return 1;
|
||||||
skip:
|
skip:
|
||||||
@ -1679,12 +1683,12 @@ static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
invalid_fld:
|
invalid_fld:
|
||||||
ata_scsi_set_sense(scmd, ILLEGAL_REQUEST, 0x24, 0x0);
|
ata_scsi_set_sense(qc->dev, scmd, ILLEGAL_REQUEST, 0x24, 0x0);
|
||||||
/* "Invalid field in cbd" */
|
/* "Invalid field in cbd" */
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
out_of_range:
|
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" */
|
/* "Logical Block Address out of range" */
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
@ -1781,12 +1785,12 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc)
|
|||||||
goto out_of_range;
|
goto out_of_range;
|
||||||
/* treat all other errors as -EINVAL, fall through */
|
/* treat all other errors as -EINVAL, fall through */
|
||||||
invalid_fld:
|
invalid_fld:
|
||||||
ata_scsi_set_sense(scmd, ILLEGAL_REQUEST, 0x24, 0x0);
|
ata_scsi_set_sense(qc->dev, scmd, ILLEGAL_REQUEST, 0x24, 0x0);
|
||||||
/* "Invalid field in cbd" */
|
/* "Invalid field in cbd" */
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
out_of_range:
|
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" */
|
/* "Logical Block Address out of range" */
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
@ -2358,6 +2362,7 @@ static unsigned int ata_msense_caching(u16 *id, u8 *buf, bool changeable)
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* ata_msense_ctl_mode - Simulate MODE SENSE control mode page
|
* ata_msense_ctl_mode - Simulate MODE SENSE control mode page
|
||||||
|
* @dev: ATA device of interest
|
||||||
* @buf: output buffer
|
* @buf: output buffer
|
||||||
* @changeable: whether changeable parameters are requested
|
* @changeable: whether changeable parameters are requested
|
||||||
*
|
*
|
||||||
@ -2366,9 +2371,12 @@ static unsigned int ata_msense_caching(u16 *id, u8 *buf, bool changeable)
|
|||||||
* LOCKING:
|
* LOCKING:
|
||||||
* None.
|
* 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);
|
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);
|
return sizeof(def_control_mpage);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2482,13 +2490,13 @@ static unsigned int ata_scsiop_mode_sense(struct ata_scsi_args *args, u8 *rbuf)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case CONTROL_MPAGE:
|
case CONTROL_MPAGE:
|
||||||
p += ata_msense_ctl_mode(p, page_control == 1);
|
p += ata_msense_ctl_mode(args->dev, p, page_control == 1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ALL_MPAGES:
|
case ALL_MPAGES:
|
||||||
p += ata_msense_rw_recovery(p, page_control == 1);
|
p += ata_msense_rw_recovery(p, page_control == 1);
|
||||||
p += ata_msense_caching(args->id, 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;
|
break;
|
||||||
|
|
||||||
default: /* invalid page code */
|
default: /* invalid page code */
|
||||||
@ -2521,12 +2529,12 @@ static unsigned int ata_scsiop_mode_sense(struct ata_scsi_args *args, u8 *rbuf)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
invalid_fld:
|
invalid_fld:
|
||||||
ata_scsi_set_sense(args->cmd, ILLEGAL_REQUEST, 0x24, 0x0);
|
ata_scsi_set_sense(dev, args->cmd, ILLEGAL_REQUEST, 0x24, 0x0);
|
||||||
/* "Invalid field in cbd" */
|
/* "Invalid field in cbd" */
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
saving_not_supp:
|
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" */
|
/* "Saving parameters not supported" */
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -3163,7 +3171,7 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
invalid_fld:
|
invalid_fld:
|
||||||
ata_scsi_set_sense(scmd, ILLEGAL_REQUEST, 0x24, 0x00);
|
ata_scsi_set_sense(dev, scmd, ILLEGAL_REQUEST, 0x24, 0x00);
|
||||||
/* "Invalid field in cdb" */
|
/* "Invalid field in cdb" */
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -3228,7 +3236,7 @@ static unsigned int ata_scsi_write_same_xlat(struct ata_queued_cmd *qc)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
invalid_fld:
|
invalid_fld:
|
||||||
ata_scsi_set_sense(scmd, ILLEGAL_REQUEST, 0x24, 0x00);
|
ata_scsi_set_sense(dev, scmd, ILLEGAL_REQUEST, 0x24, 0x00);
|
||||||
/* "Invalid field in cdb" */
|
/* "Invalid field in cdb" */
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -3279,6 +3287,51 @@ static int ata_mselect_caching(struct ata_queued_cmd *qc,
|
|||||||
return 0;
|
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
|
||||||
|
*
|
||||||
|
* 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)
|
||||||
|
{
|
||||||
|
struct ata_device *dev = qc->dev;
|
||||||
|
char mpage[CONTROL_MPAGE_LEN];
|
||||||
|
u8 d_sense;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
d_sense = buf[0] & (1 << 2);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check that read-only bits are not modified.
|
||||||
|
*/
|
||||||
|
ata_msense_ctl_mode(dev, mpage, false);
|
||||||
|
mpage[2] &= ~(1 << 2);
|
||||||
|
mpage[2] |= d_sense;
|
||||||
|
if (memcmp(mpage + 2, buf, CONTROL_MPAGE_LEN - 2) != 0)
|
||||||
|
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
|
* ata_scsiop_mode_select - Simulate MODE SELECT 6, 10 commands
|
||||||
* @qc: Storage for translated ATA taskfile
|
* @qc: Storage for translated ATA taskfile
|
||||||
@ -3381,7 +3434,10 @@ static unsigned int ata_scsi_mode_select_xlat(struct ata_queued_cmd *qc)
|
|||||||
if (ata_mselect_caching(qc, p, pg_len) < 0)
|
if (ata_mselect_caching(qc, p, pg_len) < 0)
|
||||||
goto invalid_param;
|
goto invalid_param;
|
||||||
break;
|
break;
|
||||||
|
case CONTROL_MPAGE:
|
||||||
|
if (ata_mselect_control(qc, p, pg_len) < 0)
|
||||||
|
goto invalid_param;
|
||||||
|
break;
|
||||||
default: /* invalid page code */
|
default: /* invalid page code */
|
||||||
goto invalid_param;
|
goto invalid_param;
|
||||||
}
|
}
|
||||||
@ -3397,17 +3453,17 @@ static unsigned int ata_scsi_mode_select_xlat(struct ata_queued_cmd *qc)
|
|||||||
|
|
||||||
invalid_fld:
|
invalid_fld:
|
||||||
/* "Invalid field in CDB" */
|
/* "Invalid field in CDB" */
|
||||||
ata_scsi_set_sense(scmd, ILLEGAL_REQUEST, 0x24, 0x0);
|
ata_scsi_set_sense(qc->dev, scmd, ILLEGAL_REQUEST, 0x24, 0x0);
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
invalid_param:
|
invalid_param:
|
||||||
/* "Invalid field in parameter list" */
|
/* "Invalid field in parameter list" */
|
||||||
ata_scsi_set_sense(scmd, ILLEGAL_REQUEST, 0x26, 0x0);
|
ata_scsi_set_sense(qc->dev, scmd, ILLEGAL_REQUEST, 0x26, 0x0);
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
invalid_param_len:
|
invalid_param_len:
|
||||||
/* "Parameter list length error" */
|
/* "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;
|
return 1;
|
||||||
|
|
||||||
skip:
|
skip:
|
||||||
@ -3611,12 +3667,12 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd)
|
|||||||
switch(scsicmd[0]) {
|
switch(scsicmd[0]) {
|
||||||
/* TODO: worth improving? */
|
/* TODO: worth improving? */
|
||||||
case FORMAT_UNIT:
|
case FORMAT_UNIT:
|
||||||
ata_scsi_invalid_field(cmd);
|
ata_scsi_invalid_field(dev, cmd);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case INQUIRY:
|
case INQUIRY:
|
||||||
if (scsicmd[1] & 2) /* is CmdDt set? */
|
if (scsicmd[1] & 2) /* is CmdDt set? */
|
||||||
ata_scsi_invalid_field(cmd);
|
ata_scsi_invalid_field(dev, cmd);
|
||||||
else if ((scsicmd[1] & 1) == 0) /* is EVPD clear? */
|
else if ((scsicmd[1] & 1) == 0) /* is EVPD clear? */
|
||||||
ata_scsi_rbuf_fill(&args, ata_scsiop_inq_std);
|
ata_scsi_rbuf_fill(&args, ata_scsiop_inq_std);
|
||||||
else switch (scsicmd[2]) {
|
else switch (scsicmd[2]) {
|
||||||
@ -3642,7 +3698,7 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd)
|
|||||||
ata_scsi_rbuf_fill(&args, ata_scsiop_inq_b2);
|
ata_scsi_rbuf_fill(&args, ata_scsiop_inq_b2);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ata_scsi_invalid_field(cmd);
|
ata_scsi_invalid_field(dev, cmd);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -3660,7 +3716,7 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd)
|
|||||||
if ((scsicmd[1] & 0x1f) == SAI_READ_CAPACITY_16)
|
if ((scsicmd[1] & 0x1f) == SAI_READ_CAPACITY_16)
|
||||||
ata_scsi_rbuf_fill(&args, ata_scsiop_read_cap);
|
ata_scsi_rbuf_fill(&args, ata_scsiop_read_cap);
|
||||||
else
|
else
|
||||||
ata_scsi_invalid_field(cmd);
|
ata_scsi_invalid_field(dev, cmd);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case REPORT_LUNS:
|
case REPORT_LUNS:
|
||||||
@ -3668,7 +3724,7 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case REQUEST_SENSE:
|
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->result = (DRIVER_SENSE << 24);
|
||||||
cmd->scsi_done(cmd);
|
cmd->scsi_done(cmd);
|
||||||
break;
|
break;
|
||||||
@ -3692,12 +3748,12 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd)
|
|||||||
if ((tmp8 == 0x4) && (!scsicmd[3]) && (!scsicmd[4]))
|
if ((tmp8 == 0x4) && (!scsicmd[3]) && (!scsicmd[4]))
|
||||||
ata_scsi_rbuf_fill(&args, ata_scsiop_noop);
|
ata_scsi_rbuf_fill(&args, ata_scsiop_noop);
|
||||||
else
|
else
|
||||||
ata_scsi_invalid_field(cmd);
|
ata_scsi_invalid_field(dev, cmd);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* all other commands */
|
/* all other commands */
|
||||||
default:
|
default:
|
||||||
ata_scsi_set_sense(cmd, ILLEGAL_REQUEST, 0x20, 0x0);
|
ata_scsi_set_sense(dev, cmd, ILLEGAL_REQUEST, 0x20, 0x0);
|
||||||
/* "Invalid command operation code" */
|
/* "Invalid command operation code" */
|
||||||
cmd->scsi_done(cmd);
|
cmd->scsi_done(cmd);
|
||||||
break;
|
break;
|
||||||
|
@ -138,7 +138,8 @@ extern int ata_scsi_add_hosts(struct ata_host *host,
|
|||||||
struct scsi_host_template *sht);
|
struct scsi_host_template *sht);
|
||||||
extern void ata_scsi_scan_host(struct ata_port *ap, int sync);
|
extern void ata_scsi_scan_host(struct ata_port *ap, int sync);
|
||||||
extern int ata_scsi_offline_dev(struct ata_device *dev);
|
extern int ata_scsi_offline_dev(struct ata_device *dev);
|
||||||
extern void ata_scsi_set_sense(struct scsi_cmnd *cmd, u8 sk, u8 asc, u8 ascq);
|
extern void ata_scsi_set_sense(struct ata_device *dev,
|
||||||
|
struct scsi_cmnd *cmd, u8 sk, u8 asc, u8 ascq);
|
||||||
extern void ata_scsi_set_sense_information(struct ata_device *dev,
|
extern void ata_scsi_set_sense_information(struct ata_device *dev,
|
||||||
struct scsi_cmnd *cmd,
|
struct scsi_cmnd *cmd,
|
||||||
const struct ata_taskfile *tf);
|
const struct ata_taskfile *tf);
|
||||||
|
@ -180,6 +180,7 @@ enum {
|
|||||||
ATA_DFLAG_DA = (1 << 26), /* device supports Device Attention */
|
ATA_DFLAG_DA = (1 << 26), /* device supports Device Attention */
|
||||||
ATA_DFLAG_DEVSLP = (1 << 27), /* device supports Device Sleep */
|
ATA_DFLAG_DEVSLP = (1 << 27), /* device supports Device Sleep */
|
||||||
ATA_DFLAG_ACPI_DISABLED = (1 << 28), /* ACPI for the device is disabled */
|
ATA_DFLAG_ACPI_DISABLED = (1 << 28), /* ACPI for the device is disabled */
|
||||||
|
ATA_DFLAG_D_SENSE = (1 << 29), /* Descriptor sense requested */
|
||||||
|
|
||||||
ATA_DEV_UNKNOWN = 0, /* unknown device */
|
ATA_DEV_UNKNOWN = 0, /* unknown device */
|
||||||
ATA_DEV_ATA = 1, /* ATA device */
|
ATA_DEV_ATA = 1, /* ATA device */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user