]> Git Repo - qemu.git/blobdiff - hw/scsi-disk.c
Merge remote-tracking branch 'kiszka/queues/slirp' into staging
[qemu.git] / hw / scsi-disk.c
index 734fe13c6598cfacb8a2860f93f42696955813d3..a9c727905a6233f947b2ace81f6fc381352209d7 100644 (file)
@@ -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,6 +1247,12 @@ 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 (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) {
@@ -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;
@@ -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)
@@ -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;
 }
 
This page took 0.028836 seconds and 4 git commands to generate.