microblaze: linux-user support.
[qemu] / hw / usb-msd.c
index 251bd64..3a3eb4a 100644 (file)
@@ -1,4 +1,4 @@
-/* 
+/*
  * USB Mass Storage Device emulation
  *
  * Copyright (c) 2006 CodeSourcery.
@@ -7,15 +7,19 @@
  * This code is licenced under the LGPL.
  */
 
-#include "vl.h"
+#include "qemu-common.h"
+#include "usb.h"
+#include "block.h"
+#include "scsi-disk.h"
+#include "console.h"
 
 //#define DEBUG_MSD
 
 #ifdef DEBUG_MSD
-#define DPRINTF(fmt, args...) \
-do { printf("usb-msd: " fmt , ##args); } while (0)
+#define DPRINTF(fmt, ...) \
+do { printf("usb-msd: " fmt , ## __VA_ARGS__); } while (0)
 #else
-#define DPRINTF(fmt, args...) do {} while(0)
+#define DPRINTF(fmt, ...) do {} while(0)
 #endif
 
 /* USB requests.  */
@@ -93,13 +97,13 @@ static const uint8_t qemu_msd_config_descriptor[] = {
        0x01,       /*  u8  bNumInterfaces; (1) */
        0x01,       /*  u8  bConfigurationValue; */
        0x00,       /*  u8  iConfiguration; */
-       0xc0,       /*  u8  bmAttributes; 
+       0xc0,       /*  u8  bmAttributes;
                                 Bit 7: must be set,
                                     6: Self-powered,
                                     5: Remote wakeup,
                                     4..0: resvd */
        0x00,       /*  u8  MaxPower; */
-      
+
        /* one interface */
        0x09,       /*  u8  if_bLength; */
        0x04,       /*  u8  if_bDescriptorType; Interface */
@@ -110,7 +114,7 @@ static const uint8_t qemu_msd_config_descriptor[] = {
        0x06,       /*  u8  if_bInterfaceSubClass; SCSI */
        0x50,       /*  u8  if_bInterfaceProtocol; Bulk Only */
        0x00,       /*  u8  if_iInterface; */
-     
+
        /* Bulk-In endpoint */
        0x07,       /*  u8  ep_bLength; */
        0x05,       /*  u8  ep_bDescriptorType; Endpoint */
@@ -146,9 +150,9 @@ static void usb_msd_copy_data(MSDState *s)
     s->data_len -= len;
     if (s->scsi_len == 0) {
         if (s->mode == USB_MSDM_DATAIN) {
-            scsi_read_data(s->scsi_dev, s->tag);
+            s->scsi_dev->read_data(s->scsi_dev, s->tag);
         } else if (s->mode == USB_MSDM_DATAOUT) {
-            scsi_write_data(s->scsi_dev, s->tag);
+            s->scsi_dev->write_data(s->scsi_dev, s->tag);
         }
     }
 }
@@ -201,7 +205,7 @@ static void usb_msd_command_complete(void *opaque, int reason, uint32_t tag,
         return;
     }
     s->scsi_len = arg;
-    s->scsi_buf = scsi_get_buf(s->scsi_dev, tag);
+    s->scsi_buf = s->scsi_dev->get_buf(s->scsi_dev, tag);
     if (p) {
         usb_msd_copy_data(s);
         if (s->usb_len == 0) {
@@ -259,12 +263,12 @@ static int usb_msd_handle_control(USBDevice *dev, int request, int value,
     case DeviceRequest | USB_REQ_GET_DESCRIPTOR:
         switch(value >> 8) {
         case USB_DT_DEVICE:
-            memcpy(data, qemu_msd_dev_descriptor, 
+            memcpy(data, qemu_msd_dev_descriptor,
                    sizeof(qemu_msd_dev_descriptor));
             ret = sizeof(qemu_msd_dev_descriptor);
             break;
         case USB_DT_CONFIG:
-            memcpy(data, qemu_msd_config_descriptor, 
+            memcpy(data, qemu_msd_config_descriptor,
                    sizeof(qemu_msd_config_descriptor));
             ret = sizeof(qemu_msd_config_descriptor);
             break;
@@ -339,7 +343,7 @@ static int usb_msd_handle_control(USBDevice *dev, int request, int value,
 static void usb_msd_cancel_io(USBPacket *p, void *opaque)
 {
     MSDState *s = opaque;
-    scsi_cancel_io(s->scsi_dev, s->tag);
+    s->scsi_dev->cancel_io(s->scsi_dev, s->tag);
     s->packet = NULL;
     s->scsi_len = 0;
 }
@@ -387,14 +391,14 @@ static int usb_msd_handle_data(USBDevice *dev, USBPacket *p)
             DPRINTF("Command tag 0x%x flags %08x len %d data %d\n",
                     s->tag, cbw.flags, cbw.cmd_len, s->data_len);
             s->residue = 0;
-            scsi_send_command(s->scsi_dev, s->tag, cbw.cmd, 0);
+            s->scsi_dev->send_command(s->scsi_dev, s->tag, cbw.cmd, 0);
             /* ??? Should check that USB and SCSI data transfer
                directions match.  */
             if (s->residue == 0) {
                 if (s->mode == USB_MSDM_DATAIN) {
-                    scsi_read_data(s->scsi_dev, s->tag);
+                    s->scsi_dev->read_data(s->scsi_dev, s->tag);
                 } else if (s->mode == USB_MSDM_DATAOUT) {
-                    scsi_write_data(s->scsi_dev, s->tag);
+                    s->scsi_dev->write_data(s->scsi_dev, s->tag);
                 }
             }
             ret = len;
@@ -505,7 +509,7 @@ static void usb_msd_handle_destroy(USBDevice *dev)
 {
     MSDState *s = (MSDState *)dev;
 
-    scsi_disk_destroy(s->scsi_dev);
+    s->scsi_dev->destroy(s->scsi_dev);
     bdrv_delete(s->bs);
     qemu_free(s);
 }
@@ -514,13 +518,40 @@ USBDevice *usb_msd_init(const char *filename)
 {
     MSDState *s;
     BlockDriverState *bdrv;
+    BlockDriver *drv = NULL;
+    const char *p1;
+    char fmt[32];
+
+    p1 = strchr(filename, ':');
+    if (p1++) {
+        const char *p2;
+
+        if (strstart(filename, "format=", &p2)) {
+            int len = MIN(p1 - p2, sizeof(fmt));
+            pstrcpy(fmt, len, p2);
+
+            drv = bdrv_find_format(fmt);
+            if (!drv) {
+                printf("invalid format %s\n", fmt);
+                return NULL;
+            }
+        } else if (*filename != ':') {
+            printf("unrecognized USB mass-storage option %s\n", filename);
+            return NULL;
+        }
 
-    s = qemu_mallocz(sizeof(MSDState));
-    if (!s)
+        filename = p1;
+    }
+
+    if (!*filename) {
+        printf("block device specification needed\n");
         return NULL;
+    }
+
+    s = qemu_mallocz(sizeof(MSDState));
 
     bdrv = bdrv_new("usb");
-    if (bdrv_open(bdrv, filename, 0) < 0)
+    if (bdrv_open2(bdrv, filename, 0, drv) < 0)
         goto fail;
     s->bs = bdrv;
 
@@ -542,3 +573,10 @@ USBDevice *usb_msd_init(const char *filename)
     qemu_free(s);
     return NULL;
 }
+
+BlockDriverState *usb_msd_get_bdrv(USBDevice *dev)
+{
+    MSDState *s = (MSDState *)dev;
+
+    return s->bs;
+}