X-Git-Url: https://repo.jachan.dev/qemu.git/blobdiff_plain/6a8a685c4d022d4edee57b0fb78c0ae1b4876478..22d48de65c88c42e3cb2b000491dc6089a240e2a:/hw/scsi-disk.c diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c index fb0540a3a4..a9c727905a 100644 --- a/hw/scsi-disk.c +++ b/hw/scsi-disk.c @@ -447,7 +447,7 @@ static void scsi_write_complete(void * opaque, int ret) return; } else { scsi_init_iovec(r, SCSI_DMA_BUF_SIZE); - DPRINTF("Write complete tag=0x%x more=%d\n", r->req.tag, r->qiov.size); + DPRINTF("Write complete tag=0x%x more=%zd\n", r->req.tag, r->qiov.size); scsi_req_data(&r->req, r->qiov.size); } @@ -1247,8 +1247,14 @@ static int scsi_disk_emulate_start_stop(SCSIDiskReq *r) SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev); bool start = req->cmd.buf[4] & 1; bool loej = req->cmd.buf[4] & 2; /* load on start, eject on !start */ + int pwrcnd = req->cmd.buf[4] & 0xf0; - if (s->qdev.type == TYPE_ROM && loej) { + if (pwrcnd) { + /* eject/load only happens for power condition == 0 */ + return 0; + } + + if ((s->features & (1 << SCSI_DISK_F_REMOVABLE)) && loej) { if (!start && !s->tray_open && s->tray_locked) { scsi_check_condition(r, bdrv_is_inserted(s->qdev.conf.bs) @@ -1271,7 +1277,7 @@ static void scsi_disk_emulate_read_data(SCSIRequest *req) int buflen = r->iov.iov_len; if (buflen) { - DPRINTF("Read buf_len=%zd\n", buflen); + DPRINTF("Read buf_len=%d\n", buflen); r->iov.iov_len = 0; r->started = true; scsi_req_data(&r->req, buflen); @@ -1449,7 +1455,7 @@ static void scsi_disk_emulate_write_data(SCSIRequest *req) if (r->iov.iov_len) { int buflen = r->iov.iov_len; - DPRINTF("Write buf_len=%zd\n", buflen); + DPRINTF("Write buf_len=%d\n", buflen); r->iov.iov_len = 0; scsi_req_data(&r->req, buflen); return; @@ -1860,6 +1866,19 @@ static void scsi_destroy(SCSIDevice *dev) blockdev_mark_auto_del(s->qdev.conf.bs); } +static void scsi_disk_resize_cb(void *opaque) +{ + SCSIDiskState *s = opaque; + + /* SPC lists this sense code as available only for + * direct-access devices. + */ + if (s->qdev.type == TYPE_DISK) { + scsi_device_set_ua(&s->qdev, SENSE_CODE(CAPACITY_CHANGED)); + scsi_device_report_change(&s->qdev, SENSE_CODE(CAPACITY_CHANGED)); + } +} + static void scsi_cd_change_media_cb(void *opaque, bool load) { SCSIDiskState *s = opaque; @@ -1876,7 +1895,7 @@ static void scsi_cd_change_media_cb(void *opaque, bool load) */ s->media_changed = load; s->tray_open = !load; - s->qdev.unit_attention = SENSE_CODE(UNIT_ATTENTION_NO_MEDIUM); + scsi_device_set_ua(&s->qdev, SENSE_CODE(UNIT_ATTENTION_NO_MEDIUM)); s->media_event = true; s->eject_request = false; } @@ -1901,11 +1920,17 @@ static bool scsi_cd_is_medium_locked(void *opaque) return ((SCSIDiskState *)opaque)->tray_locked; } -static const BlockDevOps scsi_cd_block_ops = { +static const BlockDevOps scsi_disk_removable_block_ops = { .change_media_cb = scsi_cd_change_media_cb, .eject_request_cb = scsi_cd_eject_request_cb, .is_tray_open = scsi_cd_is_tray_open, .is_medium_locked = scsi_cd_is_medium_locked, + + .resize_cb = scsi_disk_resize_cb, +}; + +static const BlockDevOps scsi_disk_block_ops = { + .resize_cb = scsi_disk_resize_cb, }; static void scsi_disk_unit_attention_reported(SCSIDevice *dev) @@ -1913,7 +1938,7 @@ static void scsi_disk_unit_attention_reported(SCSIDevice *dev) SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev); if (s->media_changed) { s->media_changed = false; - s->qdev.unit_attention = SENSE_CODE(MEDIUM_CHANGED); + scsi_device_set_ua(&s->qdev, SENSE_CODE(MEDIUM_CHANGED)); } } @@ -1950,7 +1975,9 @@ static int scsi_initfn(SCSIDevice *dev) } if (s->features & (1 << SCSI_DISK_F_REMOVABLE)) { - bdrv_set_dev_ops(s->qdev.conf.bs, &scsi_cd_block_ops, s); + bdrv_set_dev_ops(s->qdev.conf.bs, &scsi_disk_removable_block_ops, s); + } else { + bdrv_set_dev_ops(s->qdev.conf.bs, &scsi_disk_block_ops, s); } bdrv_set_buffer_alignment(s->qdev.conf.bs, s->qdev.blocksize); @@ -2066,23 +2093,24 @@ static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun, const SCSIReqOps *ops; uint8_t command; + command = buf[0]; + ops = scsi_disk_reqops_dispatch[command]; + if (!ops) { + ops = &scsi_disk_emulate_reqops; + } + req = scsi_req_alloc(ops, &s->qdev, tag, lun, hba_private); + #ifdef DEBUG_SCSI - DPRINTF("Command: lun=%d tag=0x%x data=0x%02x", lun, buf[0]); + DPRINTF("Command: lun=%d tag=0x%x data=0x%02x", lun, tag, buf[0]); { int i; - for (i = 1; i < r->req.cmd.len; i++) { + for (i = 1; i < req->cmd.len; i++) { printf(" 0x%02x", buf[i]); } printf("\n"); } #endif - command = buf[0]; - ops = scsi_disk_reqops_dispatch[command]; - if (!ops) { - ops = &scsi_disk_emulate_reqops; - } - req = scsi_req_alloc(ops, &s->qdev, tag, lun, hba_private); return req; }