qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH] usb-msd: Add usb-storage, removable=on|off property


From: Stefan Hajnoczi
Subject: [Qemu-devel] [PATCH] usb-msd: Add usb-storage, removable=on|off property
Date: Sat, 15 Jan 2011 00:00:43 +0000

USB Mass Storage Devices sometimes have the RMB (removable) bit set in
the SCSI INQUIRY response.  Thumbdrives tend to have the bit set whereas
hard disks do not.

Operating systems differentiate between removable devices and fixed
devices.  Under Linux, the anaconda installer looks for removable
devices.  Under Windows, only fixed devices may have more than one
partition and AutoRun is also affected by the removable bit.

For these reasons, allow USB Mass Storage Devices to override the
removable bit:

qemu -usb
     -drive if=none,file=test.img,cache=none,id=disk0
     -device usb-storage,drive=disk0,removable=on

The default is off.

Signed-off-by: Stefan Hajnoczi <address@hidden>
---
 hw/scsi-disk.c |    6 +++++-
 hw/usb-msd.c   |   19 +++++++++++++++++++
 2 files changed, 24 insertions(+), 1 deletions(-)

diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index 6cb317c..39c1279 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -548,7 +548,6 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, 
uint8_t *outbuf)
 
     if (bdrv_get_type_hint(s->bs) == BDRV_TYPE_CDROM) {
         outbuf[0] = 5;
-        outbuf[1] = 0x80;
         memcpy(&outbuf[16], "QEMU CD-ROM     ", 16);
     } else {
         outbuf[0] = 0;
@@ -557,6 +556,11 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, 
uint8_t *outbuf)
     memcpy(&outbuf[8], "QEMU    ", 8);
     memset(&outbuf[32], 0, 4);
     memcpy(&outbuf[32], s->version, MIN(4, strlen(s->version)));
+
+    if (bdrv_is_removable(s->bs)) {
+        outbuf[1] |= 0x80;
+    }
+
     /*
      * We claim conformance to SPC-3, which is required for guests
      * to ask for modern features like READ CAPACITY(16) or the
diff --git a/hw/usb-msd.c b/hw/usb-msd.c
index 0a95d8d..2dce9df 100644
--- a/hw/usb-msd.c
+++ b/hw/usb-msd.c
@@ -50,6 +50,7 @@ typedef struct {
     SCSIBus bus;
     BlockConf conf;
     SCSIDevice *scsi_dev;
+    uint32_t removable;
     int result;
     /* For async completion.  */
     USBPacket *packet;
@@ -520,6 +521,13 @@ static void usb_msd_password_cb(void *opaque, int err)
         qdev_unplug(&s->dev.qdev);
 }
 
+static void usb_msd_change_cb(void *opaque)
+{
+    MSDState *s = opaque;
+
+    qdev_unplug(&s->dev.qdev);
+}
+
 static int usb_msd_initfn(USBDevice *dev)
 {
     MSDState *s = DO_UPCAST(MSDState, dev, dev);
@@ -548,6 +556,16 @@ static int usb_msd_initfn(USBDevice *dev)
     if (!s->scsi_dev) {
         return -1;
     }
+
+    /*
+     * Allow overriding the SCSI INQUIRY removable (RMB) bit for hard disks.
+     * USB thumbdrives tend report removable media but USB hard disks do not.
+     */
+    if (s->removable && bdrv_get_type_hint(bs) == BDRV_TYPE_HD) {
+        bdrv_set_change_cb(bs, usb_msd_change_cb, s);
+        bdrv_set_removable(bs, 1);
+    }
+
     s->bus.qbus.allow_hotplug = 0;
     usb_msd_handle_reset(dev);
 
@@ -634,6 +652,7 @@ static struct USBDeviceInfo msd_info = {
     .usbdevice_init = usb_msd_init,
     .qdev.props     = (Property[]) {
         DEFINE_BLOCK_PROPERTIES(MSDState, conf),
+        DEFINE_PROP_BIT("removable", MSDState, removable, 1, false),
         DEFINE_PROP_END_OF_LIST(),
     },
 };
-- 
1.7.2.3




reply via email to

[Prev in Thread] Current Thread [Next in Thread]