Message ID | 1315328340-6192-17-git-send-email-armbru@redhat.com |
---|---|
State | New |
Headers | show |
On 09/06/2011 06:58 PM, Markus Armbruster wrote: > Don't fail when tray is already open. > > Signed-off-by: Markus Armbruster<armbru@redhat.com> > --- > hw/scsi-bus.c | 10 ++++++++++ > hw/scsi-disk.c | 15 +++++++++++---- > hw/scsi.h | 4 ++++ > 3 files changed, 25 insertions(+), 4 deletions(-) > > diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c > index 160eaee..79cb29d 100644 > --- a/hw/scsi-bus.c > +++ b/hw/scsi-bus.c > @@ -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 > diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c > index 4e89bb1..1a49217 100644 > --- a/hw/scsi-disk.c > +++ b/hw/scsi-disk.c > @@ -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; > diff --git a/hw/scsi.h b/hw/scsi.h > index 98fd689..a28cd68 100644 > --- a/hw/scsi.h > +++ b/hw/scsi.h > @@ -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 */ Matches MMC6, paragraph 6.42.3.1. Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c index 160eaee..79cb29d 100644 --- a/hw/scsi-bus.c +++ b/hw/scsi-bus.c @@ -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 diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c index 4e89bb1..1a49217 100644 --- a/hw/scsi-disk.c +++ b/hw/scsi-disk.c @@ -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; diff --git a/hw/scsi.h b/hw/scsi.h index 98fd689..a28cd68 100644 --- a/hw/scsi.h +++ b/hw/scsi.h @@ -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 */
Don't fail when tray is already open. Signed-off-by: Markus Armbruster <armbru@redhat.com> --- hw/scsi-bus.c | 10 ++++++++++ hw/scsi-disk.c | 15 +++++++++++---- hw/scsi.h | 4 ++++ 3 files changed, 25 insertions(+), 4 deletions(-)