scsi-disk: Fix START_STOP to fail when it can't eject
Don't fail when tray is already open. Signed-off-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
parent
48f65b3f52
commit
68bb01f398
@ -772,6 +772,11 @@ const struct SCSISense sense_code_NO_MEDIUM = {
|
||||
.key = NOT_READY, .asc = 0x3a, .ascq = 0x00
|
||||
};
|
||||
|
||||
/* LUN not ready, medium removal prevented */
|
||||
const struct SCSISense sense_code_NOT_READY_REMOVAL_PREVENTED = {
|
||||
.key = NOT_READY, .asc = 0x53, .ascq = 0x00
|
||||
};
|
||||
|
||||
/* Hardware error, internal target failure */
|
||||
const struct SCSISense sense_code_TARGET_FAILURE = {
|
||||
.key = HARDWARE_ERROR, .asc = 0x44, .ascq = 0x00
|
||||
@ -807,6 +812,11 @@ const struct SCSISense sense_code_INCOMPATIBLE_MEDIUM = {
|
||||
.key = ILLEGAL_REQUEST, .asc = 0x30, .ascq = 0x00
|
||||
};
|
||||
|
||||
/* Illegal request, medium removal prevented */
|
||||
const struct SCSISense sense_code_ILLEGAL_REQ_REMOVAL_PREVENTED = {
|
||||
.key = ILLEGAL_REQUEST, .asc = 0x53, .ascq = 0x00
|
||||
};
|
||||
|
||||
/* Command aborted, I/O process terminated */
|
||||
const struct SCSISense sense_code_IO_ERROR = {
|
||||
.key = ABORTED_COMMAND, .asc = 0x00, .ascq = 0x06
|
||||
|
@ -822,7 +822,7 @@ static int scsi_disk_emulate_read_toc(SCSIRequest *req, uint8_t *outbuf)
|
||||
return toclen;
|
||||
}
|
||||
|
||||
static void scsi_disk_emulate_start_stop(SCSIDiskReq *r)
|
||||
static int scsi_disk_emulate_start_stop(SCSIDiskReq *r)
|
||||
{
|
||||
SCSIRequest *req = &r->req;
|
||||
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev);
|
||||
@ -830,12 +830,17 @@ static void scsi_disk_emulate_start_stop(SCSIDiskReq *r)
|
||||
bool loej = req->cmd.buf[4] & 2; /* load on start, eject on !start */
|
||||
|
||||
if (s->qdev.type == TYPE_ROM && loej) {
|
||||
if (!start && s->tray_locked) {
|
||||
return;
|
||||
if (!start && !s->tray_open && s->tray_locked) {
|
||||
scsi_check_condition(r,
|
||||
bdrv_is_inserted(s->bs)
|
||||
? SENSE_CODE(ILLEGAL_REQ_REMOVAL_PREVENTED)
|
||||
: SENSE_CODE(NOT_READY_REMOVAL_PREVENTED));
|
||||
return -1;
|
||||
}
|
||||
bdrv_eject(s->bs, !start);
|
||||
s->tray_open = !start;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int scsi_disk_emulate_command(SCSIDiskReq *r, uint8_t *outbuf)
|
||||
@ -883,7 +888,9 @@ static int scsi_disk_emulate_command(SCSIDiskReq *r, uint8_t *outbuf)
|
||||
goto illegal_request;
|
||||
break;
|
||||
case START_STOP:
|
||||
scsi_disk_emulate_start_stop(r);
|
||||
if (scsi_disk_emulate_start_stop(r) < 0) {
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
case ALLOW_MEDIUM_REMOVAL:
|
||||
s->tray_locked = req->cmd.buf[4] & 1;
|
||||
|
@ -136,6 +136,8 @@ extern const struct SCSISense sense_code_NO_SENSE;
|
||||
extern const struct SCSISense sense_code_LUN_NOT_READY;
|
||||
/* LUN not ready, Medium not present */
|
||||
extern const struct SCSISense sense_code_NO_MEDIUM;
|
||||
/* LUN not ready, medium removal prevented */
|
||||
extern const struct SCSISense sense_code_NOT_READY_REMOVAL_PREVENTED;
|
||||
/* Hardware error, internal target failure */
|
||||
extern const struct SCSISense sense_code_TARGET_FAILURE;
|
||||
/* Illegal request, invalid command operation code */
|
||||
@ -150,6 +152,8 @@ extern const struct SCSISense sense_code_LUN_NOT_SUPPORTED;
|
||||
extern const struct SCSISense sense_code_SAVING_PARAMS_NOT_SUPPORTED;
|
||||
/* Illegal request, Incompatible format */
|
||||
extern const struct SCSISense sense_code_INCOMPATIBLE_FORMAT;
|
||||
/* Illegal request, medium removal prevented */
|
||||
extern const struct SCSISense sense_code_ILLEGAL_REQ_REMOVAL_PREVENTED;
|
||||
/* Command aborted, I/O process terminated */
|
||||
extern const struct SCSISense sense_code_IO_ERROR;
|
||||
/* Command aborted, I_T Nexus loss occurred */
|
||||
|
Loading…
Reference in New Issue
Block a user