* [Qemu-devel] [PATCH 1/7] usb core: use qdev for -usbdevice
2009-10-26 14:56 [Qemu-devel] [PATCH v2 0/7] use qdev for -usbdevice Gerd Hoffmann
@ 2009-10-26 14:56 ` Gerd Hoffmann
2009-10-26 14:56 ` [Qemu-devel] [PATCH 2/7] usb-hid: " Gerd Hoffmann
` (5 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Gerd Hoffmann @ 2009-10-26 14:56 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
This patchs adds infrastructure to handle -usbdevice via qdev callbacks.
USBDeviceInfo gets a name field (for the -usbdevice driver name) and a
callback for -usbdevice parameter parsing.
The new usbdevice_create() function walks the qdev driver list and looks
for a usb driver with a matching name. When a parameter parsing
callback is present it is called, otherwise the device is created via
usb_create_simple().
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
hw/qdev.c | 2 +-
hw/qdev.h | 1 +
hw/usb-bus.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++
hw/usb.h | 5 +++++
vl.c | 5 +++++
5 files changed, 59 insertions(+), 1 deletions(-)
diff --git a/hw/qdev.c b/hw/qdev.c
index 20f931c..b0d92d2 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -35,7 +35,7 @@ static int qdev_hotplug = 0;
/* This is a nasty hack to allow passing a NULL bus to qdev_create. */
static BusState *main_system_bus;
-static DeviceInfo *device_info_list;
+DeviceInfo *device_info_list;
static BusState *qbus_find_recursive(BusState *bus, const char *name,
const BusInfo *info);
diff --git a/hw/qdev.h b/hw/qdev.h
index b79f3e3..738470b 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -140,6 +140,7 @@ struct DeviceInfo {
BusInfo *bus_info;
struct DeviceInfo *next;
};
+extern DeviceInfo *device_info_list;
void qdev_register(DeviceInfo *info);
diff --git a/hw/usb-bus.c b/hw/usb-bus.c
index 98987a1..28b517f 100644
--- a/hw/usb-bus.c
+++ b/hw/usb-bus.c
@@ -252,3 +252,50 @@ void usb_info(Monitor *mon)
}
}
+/* handle legacy -usbdevice cmd line option */
+USBDevice *usbdevice_create(const char *cmdline)
+{
+ USBBus *bus = usb_bus_find(-1 /* any */);
+ DeviceInfo *info;
+ USBDeviceInfo *usb;
+ char driver[32], *params;
+ int len;
+
+ params = strchr(cmdline,':');
+ if (params) {
+ params++;
+ len = params - cmdline;
+ if (len > sizeof(driver))
+ len = sizeof(driver);
+ pstrcpy(driver, len, cmdline);
+ } else {
+ pstrcpy(driver, sizeof(driver), cmdline);
+ }
+
+ for (info = device_info_list; info != NULL; info = info->next) {
+ if (info->bus_info != &usb_bus_info)
+ continue;
+ usb = DO_UPCAST(USBDeviceInfo, qdev, info);
+ if (usb->usbdevice_name == NULL)
+ continue;
+ if (strcmp(usb->usbdevice_name, driver) != 0)
+ continue;
+ break;
+ }
+ if (info == NULL) {
+#if 0
+ /* no error because some drivers are not converted (yet) */
+ qemu_error("usbdevice %s not found\n", driver);
+#endif
+ return NULL;
+ }
+
+ if (!usb->usbdevice_init) {
+ if (params) {
+ qemu_error("usbdevice %s accepts no params\n", driver);
+ return NULL;
+ }
+ return usb_create_simple(bus, usb->qdev.name);
+ }
+ return usb->usbdevice_init(params);
+}
diff --git a/hw/usb.h b/hw/usb.h
index be4fcf6..62362a7 100644
--- a/hw/usb.h
+++ b/hw/usb.h
@@ -183,6 +183,10 @@ struct USBDeviceInfo {
* Returns length or one of the USB_RET_ codes.
*/
int (*handle_data)(USBDevice *dev, USBPacket *p);
+
+ /* handle legacy -usbdevice command line options */
+ const char *usbdevice_name;
+ USBDevice *(*usbdevice_init)(const char *params);
};
typedef void (*usb_attachfn)(USBPort *port, USBDevice *dev);
@@ -309,6 +313,7 @@ void usb_qdev_register(USBDeviceInfo *info);
void usb_qdev_register_many(USBDeviceInfo *info);
USBDevice *usb_create(USBBus *bus, const char *name);
USBDevice *usb_create_simple(USBBus *bus, const char *name);
+USBDevice *usbdevice_create(const char *cmdline);
void usb_register_port(USBBus *bus, USBPort *port, void *opaque, int index,
usb_attachfn attach);
void usb_unregister_port(USBBus *bus, USBPort *port);
diff --git a/vl.c b/vl.c
index eb2744e..30b5306 100644
--- a/vl.c
+++ b/vl.c
@@ -2562,6 +2562,11 @@ static int usb_device_add(const char *devname, int is_hotplug)
if (!usb_enabled)
return -1;
+ /* drivers with .usbdevice_name entry in USBDeviceInfo */
+ dev = usbdevice_create(devname);
+ if (dev)
+ goto done;
+
/* simple devices which don't need extra care */
for (i = 0; i < ARRAY_SIZE(usbdevs); i++) {
if (strcmp(devname, usbdevs[i].name) != 0)
--
1.6.2.5
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [Qemu-devel] [PATCH 2/7] usb-hid: use qdev for -usbdevice
2009-10-26 14:56 [Qemu-devel] [PATCH v2 0/7] use qdev for -usbdevice Gerd Hoffmann
2009-10-26 14:56 ` [Qemu-devel] [PATCH 1/7] usb core: " Gerd Hoffmann
@ 2009-10-26 14:56 ` Gerd Hoffmann
2009-10-26 14:56 ` [Qemu-devel] [PATCH 3/7] usb-serial and braille: " Gerd Hoffmann
` (4 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Gerd Hoffmann @ 2009-10-26 14:56 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
hw/usb-hid.c | 3 +++
hw/usb-wacom.c | 1 +
vl.c | 29 -----------------------------
3 files changed, 4 insertions(+), 29 deletions(-)
diff --git a/hw/usb-hid.c b/hw/usb-hid.c
index d1cc45e..f4a2a48 100644
--- a/hw/usb-hid.c
+++ b/hw/usb-hid.c
@@ -882,6 +882,7 @@ static struct USBDeviceInfo hid_info[] = {
{
.qdev.name = "QEMU USB Tablet",
.qdev.alias = "usb-tablet",
+ .usbdevice_name = "tablet",
.qdev.size = sizeof(USBHIDState),
.init = usb_tablet_initfn,
.handle_packet = usb_generic_handle_packet,
@@ -892,6 +893,7 @@ static struct USBDeviceInfo hid_info[] = {
},{
.qdev.name = "QEMU USB Mouse",
.qdev.alias = "usb-mouse",
+ .usbdevice_name = "mouse",
.qdev.size = sizeof(USBHIDState),
.init = usb_mouse_initfn,
.handle_packet = usb_generic_handle_packet,
@@ -902,6 +904,7 @@ static struct USBDeviceInfo hid_info[] = {
},{
.qdev.name = "QEMU USB Keyboard",
.qdev.alias = "usb-kbd",
+ .usbdevice_name = "keyboard",
.qdev.size = sizeof(USBHIDState),
.init = usb_keyboard_initfn,
.handle_packet = usb_generic_handle_packet,
diff --git a/hw/usb-wacom.c b/hw/usb-wacom.c
index fa97db2..ef61376 100644
--- a/hw/usb-wacom.c
+++ b/hw/usb-wacom.c
@@ -411,6 +411,7 @@ static int usb_wacom_initfn(USBDevice *dev)
static struct USBDeviceInfo wacom_info = {
.qdev.name = "QEMU PenPartner Tablet",
.qdev.alias = "wacom-tablet",
+ .usbdevice_name = "wacom-tablet",
.qdev.size = sizeof(USBWacomState),
.init = usb_wacom_initfn,
.handle_packet = usb_generic_handle_packet,
diff --git a/vl.c b/vl.c
index 30b5306..52ab14f 100644
--- a/vl.c
+++ b/vl.c
@@ -2533,31 +2533,10 @@ static void usb_msd_password_cb(void *opaque, int err)
dev->info->handle_destroy(dev);
}
-static struct {
- const char *name;
- const char *qdev;
-} usbdevs[] = {
- {
- .name = "mouse",
- .qdev = "QEMU USB Mouse",
- },{
- .name = "tablet",
- .qdev = "QEMU USB Tablet",
- },{
- .name = "keyboard",
- .qdev = "QEMU USB Keyboard",
- },{
- .name = "wacom-tablet",
- .qdev = "QEMU PenPartner Tablet",
- }
-};
-
static int usb_device_add(const char *devname, int is_hotplug)
{
const char *p;
- USBBus *bus = usb_bus_find(-1 /* any */);
USBDevice *dev = NULL;
- int i;
if (!usb_enabled)
return -1;
@@ -2567,14 +2546,6 @@ static int usb_device_add(const char *devname, int is_hotplug)
if (dev)
goto done;
- /* simple devices which don't need extra care */
- for (i = 0; i < ARRAY_SIZE(usbdevs); i++) {
- if (strcmp(devname, usbdevs[i].name) != 0)
- continue;
- dev = usb_create_simple(bus, usbdevs[i].qdev);
- goto done;
- }
-
/* the other ones */
if (strstart(devname, "host:", &p)) {
dev = usb_host_device_open(p);
--
1.6.2.5
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [Qemu-devel] [PATCH 3/7] usb-serial and braille: use qdev for -usbdevice
2009-10-26 14:56 [Qemu-devel] [PATCH v2 0/7] use qdev for -usbdevice Gerd Hoffmann
2009-10-26 14:56 ` [Qemu-devel] [PATCH 1/7] usb core: " Gerd Hoffmann
2009-10-26 14:56 ` [Qemu-devel] [PATCH 2/7] usb-hid: " Gerd Hoffmann
@ 2009-10-26 14:56 ` Gerd Hoffmann
2009-10-26 14:56 ` [Qemu-devel] [PATCH 4/7] usb: make attach optional Gerd Hoffmann
` (3 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Gerd Hoffmann @ 2009-10-26 14:56 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
hw/baum.c | 6 ----
hw/baum.h | 3 --
hw/usb-serial.c | 85 ++++++++++++++++++++++++++++++++++++++++++-------------
hw/usb.h | 3 --
vl.c | 6 ----
5 files changed, 65 insertions(+), 38 deletions(-)
diff --git a/hw/baum.c b/hw/baum.c
index c66e737..8a12985 100644
--- a/hw/baum.c
+++ b/hw/baum.c
@@ -627,9 +627,3 @@ fail_handle:
free(baum);
return NULL;
}
-
-USBDevice *usb_baum_init(void)
-{
- /* USB Product ID of Super Vario 40 */
- return usb_serial_init("productid=FE72:braille");
-}
diff --git a/hw/baum.h b/hw/baum.h
index 39ca4b1..8af710f 100644
--- a/hw/baum.h
+++ b/hw/baum.h
@@ -22,8 +22,5 @@
* THE SOFTWARE.
*/
-/* usb device */
-USBDevice *usb_baum_init(void);
-
/* char device */
CharDriverState *chr_baum_init(QemuOpts *opts);
diff --git a/hw/usb-serial.c b/hw/usb-serial.c
index d02f6b2..223d4c3 100644
--- a/hw/usb-serial.c
+++ b/hw/usb-serial.c
@@ -90,8 +90,8 @@ do { printf("usb-serial: " fmt , ## __VA_ARGS__); } while (0)
typedef struct {
USBDevice dev;
- uint16_t vendorid;
- uint16_t productid;
+ uint32_t vendorid;
+ uint32_t productid;
uint8_t recv_buf[RECV_BUF];
uint16_t recv_ptr;
uint16_t recv_used;
@@ -527,15 +527,18 @@ static int usb_serial_initfn(USBDevice *dev)
{
USBSerialState *s = DO_UPCAST(USBSerialState, dev, dev);
s->dev.speed = USB_SPEED_FULL;
+
+ qemu_chr_add_handlers(s->cs, usb_serial_can_read, usb_serial_read,
+ usb_serial_event, s);
+ usb_serial_handle_reset(dev);
return 0;
}
-USBDevice *usb_serial_init(const char *filename)
+static USBDevice *usb_serial_init(const char *filename)
{
USBDevice *dev;
- USBSerialState *s;
CharDriverState *cdrv;
- unsigned short vendorid = 0x0403, productid = 0x6001;
+ uint32_t vendorid = 0, productid = 0;
char label[32];
static int index;
@@ -545,26 +548,26 @@ USBDevice *usb_serial_init(const char *filename)
if (strstart(filename, "vendorid=", &p)) {
vendorid = strtol(p, &e, 16);
if (e == p || (*e && *e != ',' && *e != ':')) {
- printf("bogus vendor ID %s\n", p);
+ qemu_error("bogus vendor ID %s\n", p);
return NULL;
}
filename = e;
} else if (strstart(filename, "productid=", &p)) {
productid = strtol(p, &e, 16);
if (e == p || (*e && *e != ',' && *e != ':')) {
- printf("bogus product ID %s\n", p);
+ qemu_error("bogus product ID %s\n", p);
return NULL;
}
filename = e;
} else {
- printf("unrecognized serial USB option %s\n", filename);
+ qemu_error("unrecognized serial USB option %s\n", filename);
return NULL;
}
while(*filename == ',')
filename++;
}
if (!*filename) {
- printf("character device specification needed\n");
+ qemu_error("character device specification needed\n");
return NULL;
}
filename++;
@@ -574,23 +577,56 @@ USBDevice *usb_serial_init(const char *filename)
if (!cdrv)
return NULL;
- dev = usb_create_simple(NULL /* FIXME */, "QEMU USB Serial");
- s = DO_UPCAST(USBSerialState, dev, dev);
- s->cs = cdrv;
- s->vendorid = vendorid;
- s->productid = productid;
- snprintf(s->dev.devname, sizeof(s->dev.devname), "QEMU USB Serial(%.16s)",
- filename);
+ dev = usb_create(NULL /* FIXME */, "QEMU USB Serial");
+ qdev_prop_set_chr(&dev->qdev, "chardev", cdrv);
+ if (vendorid)
+ qdev_prop_set_uint16(&dev->qdev, "vendorid", vendorid);
+ if (productid)
+ qdev_prop_set_uint16(&dev->qdev, "productid", productid);
+ qdev_init(&dev->qdev);
- qemu_chr_add_handlers(cdrv, usb_serial_can_read, usb_serial_read,
- usb_serial_event, s);
+ return dev;
+}
+
+static USBDevice *usb_braille_init(const char *unused)
+{
+ USBDevice *dev;
+ CharDriverState *cdrv;
+
+ cdrv = qemu_chr_open("braille", "braille", NULL);
+ if (!cdrv)
+ return NULL;
- usb_serial_handle_reset((USBDevice *)s);
- return (USBDevice *)s;
+ dev = usb_create(NULL /* FIXME */, "QEMU USB Braille");
+ qdev_prop_set_chr(&dev->qdev, "chardev", cdrv);
+ qdev_init(&dev->qdev);
+
+ return dev;
}
static struct USBDeviceInfo serial_info = {
.qdev.name = "QEMU USB Serial",
+ .qdev.alias = "usb-serial",
+ .qdev.size = sizeof(USBSerialState),
+ .init = usb_serial_initfn,
+ .handle_packet = usb_generic_handle_packet,
+ .handle_reset = usb_serial_handle_reset,
+ .handle_control = usb_serial_handle_control,
+ .handle_data = usb_serial_handle_data,
+ .handle_destroy = usb_serial_handle_destroy,
+ .usbdevice_name = "serial",
+ .usbdevice_init = usb_serial_init,
+ .qdev.props = (Property[]) {
+ DEFINE_PROP_CHR("chardev", USBSerialState, cs),
+ DEFINE_PROP_HEX32("vendorid", USBSerialState, vendorid, 0x0403),
+ DEFINE_PROP_HEX32("productid", USBSerialState, productid, 0x6001),
+ DEFINE_PROP_END_OF_LIST(),
+ },
+};
+
+static struct USBDeviceInfo braille_info = {
+ .qdev.name = "QEMU USB Braille",
+ .qdev.alias = "usb-braille",
.qdev.size = sizeof(USBSerialState),
.init = usb_serial_initfn,
.handle_packet = usb_generic_handle_packet,
@@ -598,10 +634,19 @@ static struct USBDeviceInfo serial_info = {
.handle_control = usb_serial_handle_control,
.handle_data = usb_serial_handle_data,
.handle_destroy = usb_serial_handle_destroy,
+ .usbdevice_name = "braille",
+ .usbdevice_init = usb_braille_init,
+ .qdev.props = (Property[]) {
+ DEFINE_PROP_CHR("chardev", USBSerialState, cs),
+ DEFINE_PROP_HEX32("vendorid", USBSerialState, vendorid, 0x0403),
+ DEFINE_PROP_HEX32("productid", USBSerialState, productid, 0xfe72),
+ DEFINE_PROP_END_OF_LIST(),
+ },
};
static void usb_serial_register_devices(void)
{
usb_qdev_register(&serial_info);
+ usb_qdev_register(&braille_info);
}
device_init(usb_serial_register_devices)
diff --git a/hw/usb.h b/hw/usb.h
index 62362a7..a875d5b 100644
--- a/hw/usb.h
+++ b/hw/usb.h
@@ -265,9 +265,6 @@ USBDevice *usb_net_init(NICInfo *nd);
/* usb-bt.c */
USBDevice *usb_bt_init(HCIInfo *hci);
-/* usb-serial.c */
-USBDevice *usb_serial_init(const char *filename);
-
/* usb ports of the VM */
#define VM_USB_HUB_SIZE 8
diff --git a/vl.c b/vl.c
index 52ab14f..64761cf 100644
--- a/vl.c
+++ b/vl.c
@@ -2564,12 +2564,6 @@ static int usb_device_add(const char *devname, int is_hotplug)
return 0;
}
}
- } else if (strstart(devname, "serial:", &p)) {
- dev = usb_serial_init(p);
-#ifdef CONFIG_BRLAPI
- } else if (!strcmp(devname, "braille")) {
- dev = usb_baum_init();
-#endif
} else if (strstart(devname, "net:", &p)) {
QemuOpts *opts;
int idx;
--
1.6.2.5
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [Qemu-devel] [PATCH 4/7] usb: make attach optional.
2009-10-26 14:56 [Qemu-devel] [PATCH v2 0/7] use qdev for -usbdevice Gerd Hoffmann
` (2 preceding siblings ...)
2009-10-26 14:56 ` [Qemu-devel] [PATCH 3/7] usb-serial and braille: " Gerd Hoffmann
@ 2009-10-26 14:56 ` Gerd Hoffmann
2009-10-26 14:56 ` [Qemu-devel] [PATCH 5/7] usb-storage: use qdev for -usbdevice Gerd Hoffmann
` (2 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Gerd Hoffmann @ 2009-10-26 14:56 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
Add a auto_attach field to USBDevice, which is enabled by default.
USB drivers can clear this field in case they do *not* want the device
being attached (i.e. plugged into a usb port) automatically after
successfull init().
Use cases (see next patches):
* attaching encrypted mass storage devices.
* -usbdevice host:...
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
hw/usb-bus.c | 3 ++-
hw/usb.h | 1 +
2 files changed, 3 insertions(+), 1 deletions(-)
diff --git a/hw/usb-bus.c b/hw/usb-bus.c
index 28b517f..87dcc7f 100644
--- a/hw/usb-bus.c
+++ b/hw/usb-bus.c
@@ -45,8 +45,9 @@ static int usb_qdev_init(DeviceState *qdev, DeviceInfo *base)
pstrcpy(dev->devname, sizeof(dev->devname), qdev->info->name);
dev->info = info;
+ dev->auto_attach = 1;
rc = dev->info->init(dev);
- if (rc == 0)
+ if (rc == 0 && dev->auto_attach)
usb_device_attach(dev);
return rc;
}
diff --git a/hw/usb.h b/hw/usb.h
index a875d5b..a01f334 100644
--- a/hw/usb.h
+++ b/hw/usb.h
@@ -133,6 +133,7 @@ struct USBDevice {
int speed;
uint8_t addr;
char devname[32];
+ int auto_attach;
int attached;
int state;
--
1.6.2.5
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [Qemu-devel] [PATCH 5/7] usb-storage: use qdev for -usbdevice
2009-10-26 14:56 [Qemu-devel] [PATCH v2 0/7] use qdev for -usbdevice Gerd Hoffmann
` (3 preceding siblings ...)
2009-10-26 14:56 ` [Qemu-devel] [PATCH 4/7] usb: make attach optional Gerd Hoffmann
@ 2009-10-26 14:56 ` Gerd Hoffmann
2009-10-26 14:56 ` [Qemu-devel] [PATCH 6/7] usb-host: use qdev for -usbdevice + rework Gerd Hoffmann
2009-10-26 14:56 ` [Qemu-devel] [PATCH 7/7] usb: print attached status in info qtree Gerd Hoffmann
6 siblings, 0 replies; 8+ messages in thread
From: Gerd Hoffmann @ 2009-10-26 14:56 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
Hook up usb_msd_init.
Also rework handling of encrypted block devices,
move the code out vl.c.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
hw/usb-msd.c | 33 +++++++++++++++++++++++++--------
hw/usb.h | 4 ----
vl.c | 25 -------------------------
3 files changed, 25 insertions(+), 37 deletions(-)
diff --git a/hw/usb-msd.c b/hw/usb-msd.c
index dd3010e..8dc494f 100644
--- a/hw/usb-msd.c
+++ b/hw/usb-msd.c
@@ -14,6 +14,7 @@
#include "block.h"
#include "scsi-disk.h"
#include "console.h"
+#include "monitor.h"
//#define DEBUG_MSD
@@ -508,6 +509,16 @@ static int usb_msd_handle_data(USBDevice *dev, USBPacket *p)
return ret;
}
+static void usb_msd_password_cb(void *opaque, int err)
+{
+ MSDState *s = opaque;
+
+ if (!err)
+ usb_device_attach(&s->dev);
+ else
+ qdev_unplug(&s->dev.qdev);
+}
+
static int usb_msd_initfn(USBDevice *dev)
{
MSDState *s = DO_UPCAST(MSDState, dev, dev);
@@ -522,10 +533,21 @@ static int usb_msd_initfn(USBDevice *dev)
s->scsi_dev = scsi_bus_legacy_add_drive(&s->bus, s->dinfo, 0);
s->bus.qbus.allow_hotplug = 0;
usb_msd_handle_reset(dev);
+
+ if (bdrv_key_required(s->dinfo->bdrv)) {
+ if (s->dev.qdev.hotplugged) {
+ monitor_read_bdrv_key_start(cur_mon, s->dinfo->bdrv,
+ usb_msd_password_cb, s);
+ s->dev.auto_attach = 0;
+ } else {
+ autostart = 0;
+ }
+ }
+
return 0;
}
-USBDevice *usb_msd_init(const char *filename)
+static USBDevice *usb_msd_init(const char *filename)
{
static int nr=0;
char id[8];
@@ -577,13 +599,6 @@ USBDevice *usb_msd_init(const char *filename)
return dev;
}
-BlockDriverState *usb_msd_get_bdrv(USBDevice *dev)
-{
- MSDState *s = (MSDState *)dev;
-
- return s->dinfo->bdrv;
-}
-
static struct USBDeviceInfo msd_info = {
.qdev.name = "QEMU USB MSD",
.qdev.alias = "usb-storage",
@@ -593,6 +608,8 @@ static struct USBDeviceInfo msd_info = {
.handle_reset = usb_msd_handle_reset,
.handle_control = usb_msd_handle_control,
.handle_data = usb_msd_handle_data,
+ .usbdevice_name = "disk",
+ .usbdevice_init = usb_msd_init,
.qdev.props = (Property[]) {
DEFINE_PROP_DRIVE("drive", MSDState, dinfo),
DEFINE_PROP_END_OF_LIST(),
diff --git a/hw/usb.h b/hw/usb.h
index a01f334..351c466 100644
--- a/hw/usb.h
+++ b/hw/usb.h
@@ -256,10 +256,6 @@ void usb_host_info(Monitor *mon);
/* usb-hid.c */
void usb_hid_datain_cb(USBDevice *dev, void *opaque, void (*datain)(void *));
-/* usb-msd.c */
-USBDevice *usb_msd_init(const char *filename);
-BlockDriverState *usb_msd_get_bdrv(USBDevice *dev);
-
/* usb-net.c */
USBDevice *usb_net_init(NICInfo *nd);
diff --git a/vl.c b/vl.c
index 64761cf..994065c 100644
--- a/vl.c
+++ b/vl.c
@@ -2523,16 +2523,6 @@ static void smp_parse(const char *optarg)
/***********************************************************/
/* USB devices */
-static void usb_msd_password_cb(void *opaque, int err)
-{
- USBDevice *dev = opaque;
-
- if (!err)
- usb_device_attach(dev);
- else
- dev->info->handle_destroy(dev);
-}
-
static int usb_device_add(const char *devname, int is_hotplug)
{
const char *p;
@@ -2549,21 +2539,6 @@ static int usb_device_add(const char *devname, int is_hotplug)
/* the other ones */
if (strstart(devname, "host:", &p)) {
dev = usb_host_device_open(p);
- } else if (strstart(devname, "disk:", &p)) {
- BlockDriverState *bs;
-
- dev = usb_msd_init(p);
- if (!dev)
- return -1;
- bs = usb_msd_get_bdrv(dev);
- if (bdrv_key_required(bs)) {
- autostart = 0;
- if (is_hotplug) {
- monitor_read_bdrv_key_start(cur_mon, bs, usb_msd_password_cb,
- dev);
- return 0;
- }
- }
} else if (strstart(devname, "net:", &p)) {
QemuOpts *opts;
int idx;
--
1.6.2.5
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [Qemu-devel] [PATCH 6/7] usb-host: use qdev for -usbdevice + rework.
2009-10-26 14:56 [Qemu-devel] [PATCH v2 0/7] use qdev for -usbdevice Gerd Hoffmann
` (4 preceding siblings ...)
2009-10-26 14:56 ` [Qemu-devel] [PATCH 5/7] usb-storage: use qdev for -usbdevice Gerd Hoffmann
@ 2009-10-26 14:56 ` Gerd Hoffmann
2009-10-26 14:56 ` [Qemu-devel] [PATCH 7/7] usb: print attached status in info qtree Gerd Hoffmann
6 siblings, 0 replies; 8+ messages in thread
From: Gerd Hoffmann @ 2009-10-26 14:56 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
Changes:
* We don't create/delete devices, we attach/detach them instead.
* The separate autofilter list is gone, we simply walk the list
of devices directly instead.
* Autofiltering is done unconditionally now. Non-auto device scan
code got dropped.
* Autofiltering turns off the timer if there is nothing to do, it
runs only in case there are unattached host devices.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
usb-linux.c | 410 +++++++++++++++++++++--------------------------------------
1 files changed, 144 insertions(+), 266 deletions(-)
diff --git a/usb-linux.c b/usb-linux.c
index 9e5d9c4..c1706a9 100644
--- a/usb-linux.c
+++ b/usb-linux.c
@@ -64,10 +64,8 @@ struct usb_ctrlrequest {
typedef int USBScanFunc(void *opaque, int bus_num, int addr, int class_id,
int vendor_id, int product_id,
const char *product_name, int speed);
-static int usb_host_find_device(int *pbus_num, int *paddr,
- char *product_name, int product_name_size,
- const char *devname);
-//#define DEBUG
+
+#define DEBUG
#ifdef DEBUG
#define dprintf printf
@@ -118,6 +116,13 @@ struct ctrl_struct {
uint8_t buffer[2048];
};
+struct USBAutoFilter {
+ uint32_t bus_num;
+ uint32_t addr;
+ uint32_t vendor_id;
+ uint32_t product_id;
+};
+
typedef struct USBHostDevice {
USBDevice dev;
int fd;
@@ -134,10 +139,17 @@ typedef struct USBHostDevice {
/* Host side address */
int bus_num;
int addr;
+ struct USBAutoFilter match;
- struct USBHostDevice *next;
+ QTAILQ_ENTRY(USBHostDevice) next;
} USBHostDevice;
+static QTAILQ_HEAD(, USBHostDevice) hostdevs = QTAILQ_HEAD_INITIALIZER(hostdevs);
+
+static int usb_host_close(USBHostDevice *dev);
+static int parse_filter(const char *spec, struct USBAutoFilter *f);
+static void usb_host_auto_check(void *unused);
+
static int is_isoc(USBHostDevice *s, int ep)
{
return s->endp_table[ep - 1].type == USBDEVFS_URB_TYPE_ISO;
@@ -158,41 +170,6 @@ static void set_halt(USBHostDevice *s, int ep)
s->endp_table[ep - 1].halted = 1;
}
-static USBHostDevice *hostdev_list;
-
-static void hostdev_link(USBHostDevice *dev)
-{
- dev->next = hostdev_list;
- hostdev_list = dev;
-}
-
-static void hostdev_unlink(USBHostDevice *dev)
-{
- USBHostDevice *pdev = hostdev_list;
- USBHostDevice **prev = &hostdev_list;
-
- while (pdev) {
- if (pdev == dev) {
- *prev = dev->next;
- return;
- }
-
- prev = &pdev->next;
- pdev = pdev->next;
- }
-}
-
-static USBHostDevice *hostdev_find(int bus_num, int addr)
-{
- USBHostDevice *s = hostdev_list;
- while (s) {
- if (s->bus_num == bus_num && s->addr == addr)
- return s;
- s = s->next;
- }
- return NULL;
-}
-
/*
* Async URB state.
* We always allocate one isoc descriptor even for bulk transfers
@@ -252,7 +229,8 @@ static void async_complete(void *opaque)
if (errno == ENODEV && !s->closing) {
printf("husb: device %d.%d disconnected\n", s->bus_num, s->addr);
- usb_device_delete_addr(s->bus_num, s->dev.addr);
+ usb_host_close(s);
+ usb_host_auto_check(NULL);
return;
}
@@ -405,7 +383,7 @@ static int usb_host_release_interfaces(USBHostDevice *s)
static void usb_host_handle_reset(USBDevice *dev)
{
- USBHostDevice *s = (USBHostDevice *) dev;
+ USBHostDevice *s = DO_UPCAST(USBHostDevice, dev, dev);
dprintf("husb: reset device %u.%u\n", s->bus_num, s->addr);
@@ -418,18 +396,8 @@ static void usb_host_handle_destroy(USBDevice *dev)
{
USBHostDevice *s = (USBHostDevice *)dev;
- s->closing = 1;
-
- qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
-
- hostdev_unlink(s);
-
- async_complete(s);
-
- if (s->fd >= 0)
- close(s->fd);
-
- qemu_free(s);
+ usb_host_close(s);
+ QTAILQ_REMOVE(&hostdevs, s, next);
}
static int usb_linux_update_endp_table(USBHostDevice *s);
@@ -889,19 +857,16 @@ static int usb_linux_update_endp_table(USBHostDevice *s)
return 0;
}
-static int usb_host_initfn(USBDevice *dev)
-{
- return 0;
-}
-
-static USBDevice *usb_host_device_open_addr(int bus_num, int addr, const char *prod_name)
+static int usb_host_open(USBHostDevice *dev, int bus_num,
+ int addr, const char *prod_name)
{
int fd = -1, ret;
- USBDevice *d = NULL;
- USBHostDevice *dev;
struct usbdevfs_connectinfo ci;
char buf[1024];
+ if (dev->fd != -1)
+ goto fail;
+
printf("husb: open device %d.%d\n", bus_num, addr);
if (!usb_host_device_path) {
@@ -917,9 +882,6 @@ static USBDevice *usb_host_device_open_addr(int bus_num, int addr, const char *p
}
dprintf("husb: opened %s\n", buf);
- d = usb_create(NULL /* FIXME */, "USB Host Device");
- dev = DO_UPCAST(USBHostDevice, dev, d);
-
dev->bus_num = bus_num;
dev->addr = addr;
dev->fd = fd;
@@ -978,32 +940,59 @@ static USBDevice *usb_host_device_open_addr(int bus_num, int addr, const char *p
/* USB devio uses 'write' flag to check for async completions */
qemu_set_fd_handler(dev->fd, NULL, async_complete, dev);
- hostdev_link(dev);
-
- if (qdev_init(&d->qdev) < 0)
- goto fail_no_qdev;
- return (USBDevice *) dev;
+ usb_device_attach(&dev->dev);
+ return 0;
fail:
- if (d)
- qdev_free(&d->qdev);
-fail_no_qdev:
+ dev->fd = -1;
if (fd != -1)
close(fd);
- return NULL;
+ return -1;
+}
+
+static int usb_host_close(USBHostDevice *dev)
+{
+ if (dev->fd == -1)
+ return -1;
+
+ qemu_set_fd_handler(dev->fd, NULL, NULL, NULL);
+ dev->closing = 1;
+ async_complete(dev);
+ dev->closing = 0;
+ usb_device_detach(&dev->dev);
+ close(dev->fd);
+ dev->fd = -1;
+ return 0;
+}
+
+static int usb_host_initfn(USBDevice *dev)
+{
+ USBHostDevice *s = DO_UPCAST(USBHostDevice, dev, dev);
+
+ dev->auto_attach = 0;
+ s->fd = -1;
+ QTAILQ_INSERT_TAIL(&hostdevs, s, next);
+ usb_host_auto_check(NULL);
+ return 0;
}
static struct USBDeviceInfo usb_host_dev_info = {
.qdev.name = "USB Host Device",
+ .qdev.alias = "usb-host",
.qdev.size = sizeof(USBHostDevice),
.init = usb_host_initfn,
.handle_packet = usb_host_handle_packet,
.handle_reset = usb_host_handle_reset,
-#if 0
- .handle_control = usb_host_handle_control,
- .handle_data = usb_host_handle_data,
-#endif
.handle_destroy = usb_host_handle_destroy,
+ .usbdevice_name = "host",
+ .usbdevice_init = usb_host_device_open,
+ .qdev.props = (Property[]) {
+ DEFINE_PROP_UINT32("hostbus", USBHostDevice, match.bus_num, 0),
+ DEFINE_PROP_UINT32("hostaddr", USBHostDevice, match.addr, 0),
+ DEFINE_PROP_HEX32("vendorid", USBHostDevice, match.vendor_id, 0),
+ DEFINE_PROP_HEX32("productid", USBHostDevice, match.product_id, 0),
+ DEFINE_PROP_END_OF_LIST(),
+ },
};
static void usb_host_register_devices(void)
@@ -1012,35 +1001,46 @@ static void usb_host_register_devices(void)
}
device_init(usb_host_register_devices)
-static int usb_host_auto_add(const char *spec);
-static int usb_host_auto_del(const char *spec);
-
USBDevice *usb_host_device_open(const char *devname)
{
- Monitor *mon = cur_mon;
- int bus_num, addr;
- char product_name[PRODUCT_NAME_SZ];
+ struct USBAutoFilter filter = { 0, 0, 0, 0 };
+ USBDevice *dev;
+ USBHostDevice *s;
+ char *p;
+
+ dev = usb_create(NULL /* FIXME */, "USB Host Device");
+ s = DO_UPCAST(USBHostDevice, dev, dev);
if (strstr(devname, "auto:")) {
- usb_host_auto_add(devname);
- return NULL;
+ if (parse_filter(devname+5, &filter) < 0)
+ goto fail;
+ } else {
+ if ((p = strchr(devname, '.'))) {
+ filter.bus_num = strtoul(devname, NULL, 0);
+ filter.addr = strtoul(devname, NULL, 0);
+ } else if ((p = strchr(devname, ':'))) {
+ filter.vendor_id = strtoul(devname, NULL, 16);
+ filter.product_id = strtoul(devname, NULL, 16);
+ } else {
+ goto fail;
+ }
}
- if (usb_host_find_device(&bus_num, &addr, product_name, sizeof(product_name),
- devname) < 0)
- return NULL;
+ qdev_prop_set_uint32(&dev->qdev, "bus", filter.bus_num);
+ qdev_prop_set_uint32(&dev->qdev, "addr", filter.addr);
+ qdev_prop_set_uint32(&dev->qdev, "vendorid", filter.vendor_id);
+ qdev_prop_set_uint32(&dev->qdev, "productid", filter.product_id);
+ qdev_init(&dev->qdev);
+ return dev;
- if (hostdev_find(bus_num, addr)) {
- monitor_printf(mon, "husb: host usb device %d.%d is already open\n",
- bus_num, addr);
- return NULL;
- }
-
- return usb_host_device_open_addr(bus_num, addr, product_name);
+fail:
+ qdev_free(&dev->qdev);
+ return NULL;
}
int usb_host_device_close(const char *devname)
{
+#if 0
char product_name[PRODUCT_NAME_SZ];
int bus_num, addr;
USBHostDevice *s;
@@ -1057,6 +1057,7 @@ int usb_host_device_close(const char *devname)
usb_device_delete_addr(s->bus_num, s->dev.addr);
return 0;
}
+#endif
return -1;
}
@@ -1183,7 +1184,9 @@ static int usb_host_scan_dev(void *opaque, USBScanFunc *func)
*/
static int usb_host_read_file(char *line, size_t line_size, const char *device_file, const char *device_name)
{
+#if 0
Monitor *mon = cur_mon;
+#endif
FILE *f;
int ret = 0;
char filename[PATH_MAX];
@@ -1195,8 +1198,10 @@ static int usb_host_read_file(char *line, size_t line_size, const char *device_f
fgets(line, line_size, f);
fclose(f);
ret = 1;
+#if 0
} else {
monitor_printf(mon, "husb: could not open %s\n", filename);
+#endif
}
return ret;
@@ -1354,58 +1359,72 @@ static int usb_host_scan(void *opaque, USBScanFunc *func)
return ret;
}
-struct USBAutoFilter {
- struct USBAutoFilter *next;
- int bus_num;
- int addr;
- int vendor_id;
- int product_id;
-};
-
static QEMUTimer *usb_auto_timer;
-static struct USBAutoFilter *usb_auto_filter;
static int usb_host_auto_scan(void *opaque, int bus_num, int addr,
- int class_id, int vendor_id, int product_id,
- const char *product_name, int speed)
+ int class_id, int vendor_id, int product_id,
+ const char *product_name, int speed)
{
struct USBAutoFilter *f;
- struct USBDevice *dev;
+ struct USBHostDevice *s;
/* Ignore hubs */
if (class_id == 9)
return 0;
- for (f = usb_auto_filter; f; f = f->next) {
- if (f->bus_num >= 0 && f->bus_num != bus_num)
+ QTAILQ_FOREACH(s, &hostdevs, next) {
+ f = &s->match;
+
+ if (f->bus_num > 0 && f->bus_num != bus_num)
continue;
- if (f->addr >= 0 && f->addr != addr)
+ if (f->addr > 0 && f->addr != addr)
continue;
- if (f->vendor_id >= 0 && f->vendor_id != vendor_id)
+ if (f->vendor_id > 0 && f->vendor_id != vendor_id)
continue;
- if (f->product_id >= 0 && f->product_id != product_id)
+ if (f->product_id > 0 && f->product_id != product_id)
continue;
/* We got a match */
/* Already attached ? */
- if (hostdev_find(bus_num, addr))
+ if (s->fd != -1)
return 0;
dprintf("husb: auto open: bus_num %d addr %d\n", bus_num, addr);
- dev = usb_host_device_open_addr(bus_num, addr, product_name);
+ usb_host_open(s, bus_num, addr, product_name);
}
return 0;
}
-static void usb_host_auto_timer(void *unused)
+static void usb_host_auto_check(void *unused)
{
+ struct USBHostDevice *s;
+ int unconnected = 0;
+
usb_host_scan(NULL, usb_host_auto_scan);
+
+ QTAILQ_FOREACH(s, &hostdevs, next) {
+ if (s->fd == -1)
+ unconnected++;
+ }
+
+ if (unconnected == 0) {
+ /* nothing to watch */
+ if (usb_auto_timer)
+ qemu_del_timer(usb_auto_timer);
+ return;
+ }
+
+ if (!usb_auto_timer) {
+ usb_auto_timer = qemu_new_timer(rt_clock, usb_host_auto_check, NULL);
+ if (!usb_auto_timer)
+ return;
+ }
qemu_mod_timer(usb_auto_timer, qemu_get_clock(rt_clock) + 2000);
}
@@ -1457,150 +1476,6 @@ static int parse_filter(const char *spec, struct USBAutoFilter *f)
return 0;
}
-static int match_filter(const struct USBAutoFilter *f1,
- const struct USBAutoFilter *f2)
-{
- return f1->bus_num == f2->bus_num &&
- f1->addr == f2->addr &&
- f1->vendor_id == f2->vendor_id &&
- f1->product_id == f2->product_id;
-}
-
-static int usb_host_auto_add(const char *spec)
-{
- struct USBAutoFilter filter, *f;
-
- if (parse_filter(spec, &filter) < 0)
- return -1;
-
- f = qemu_mallocz(sizeof(*f));
-
- *f = filter;
-
- if (!usb_auto_filter) {
- /*
- * First entry. Init and start the monitor.
- * Right now we're using timer to check for new devices.
- * If this turns out to be too expensive we can move that into a
- * separate thread.
- */
- usb_auto_timer = qemu_new_timer(rt_clock, usb_host_auto_timer, NULL);
- if (!usb_auto_timer) {
- fprintf(stderr, "husb: failed to allocate auto scan timer\n");
- qemu_free(f);
- return -1;
- }
-
- /* Check for new devices every two seconds */
- qemu_mod_timer(usb_auto_timer, qemu_get_clock(rt_clock) + 2000);
- }
-
- dprintf("husb: added auto filter: bus_num %d addr %d vid %d pid %d\n",
- f->bus_num, f->addr, f->vendor_id, f->product_id);
-
- f->next = usb_auto_filter;
- usb_auto_filter = f;
-
- return 0;
-}
-
-static int usb_host_auto_del(const char *spec)
-{
- struct USBAutoFilter *pf = usb_auto_filter;
- struct USBAutoFilter **prev = &usb_auto_filter;
- struct USBAutoFilter filter;
-
- if (parse_filter(spec, &filter) < 0)
- return -1;
-
- while (pf) {
- if (match_filter(pf, &filter)) {
- dprintf("husb: removed auto filter: bus_num %d addr %d vid %d pid %d\n",
- pf->bus_num, pf->addr, pf->vendor_id, pf->product_id);
-
- *prev = pf->next;
-
- if (!usb_auto_filter) {
- /* No more filters. Stop scanning. */
- qemu_del_timer(usb_auto_timer);
- qemu_free_timer(usb_auto_timer);
- }
-
- return 0;
- }
-
- prev = &pf->next;
- pf = pf->next;
- }
-
- return -1;
-}
-
-typedef struct FindDeviceState {
- int vendor_id;
- int product_id;
- int bus_num;
- int addr;
- char product_name[PRODUCT_NAME_SZ];
-} FindDeviceState;
-
-static int usb_host_find_device_scan(void *opaque, int bus_num, int addr,
- int class_id,
- int vendor_id, int product_id,
- const char *product_name, int speed)
-{
- FindDeviceState *s = opaque;
- if ((vendor_id == s->vendor_id &&
- product_id == s->product_id) ||
- (bus_num == s->bus_num &&
- addr == s->addr)) {
- pstrcpy(s->product_name, PRODUCT_NAME_SZ, product_name);
- s->bus_num = bus_num;
- s->addr = addr;
- return 1;
- } else {
- return 0;
- }
-}
-
-/* the syntax is :
- 'bus.addr' (decimal numbers) or
- 'vendor_id:product_id' (hexa numbers) */
-static int usb_host_find_device(int *pbus_num, int *paddr,
- char *product_name, int product_name_size,
- const char *devname)
-{
- const char *p;
- int ret;
- FindDeviceState fs;
-
- p = strchr(devname, '.');
- if (p) {
- *pbus_num = strtoul(devname, NULL, 0);
- *paddr = strtoul(p + 1, NULL, 0);
- fs.bus_num = *pbus_num;
- fs.addr = *paddr;
- ret = usb_host_scan(&fs, usb_host_find_device_scan);
- if (ret)
- pstrcpy(product_name, product_name_size, fs.product_name);
- return 0;
- }
-
- p = strchr(devname, ':');
- if (p) {
- fs.vendor_id = strtoul(devname, NULL, 16);
- fs.product_id = strtoul(p + 1, NULL, 16);
- ret = usb_host_scan(&fs, usb_host_find_device_scan);
- if (ret) {
- *pbus_num = fs.bus_num;
- *paddr = fs.addr;
- pstrcpy(product_name, product_name_size, fs.product_name);
- return 0;
- }
- }
- return -1;
-}
-
/**********************/
/* USB host device info */
@@ -1686,7 +1561,7 @@ static int usb_host_info_device(void *opaque, int bus_num, int addr,
static void dec2str(int val, char *str, size_t size)
{
- if (val == -1)
+ if (val == 0)
snprintf(str, size, "*");
else
snprintf(str, size, "%d", val);
@@ -1694,22 +1569,25 @@ static void dec2str(int val, char *str, size_t size)
static void hex2str(int val, char *str, size_t size)
{
- if (val == -1)
+ if (val == 0)
snprintf(str, size, "*");
else
- snprintf(str, size, "%x", val);
+ snprintf(str, size, "%04x", val);
}
void usb_host_info(Monitor *mon)
{
struct USBAutoFilter *f;
+ struct USBHostDevice *s;
usb_host_scan(mon, usb_host_info_device);
- if (usb_auto_filter)
- monitor_printf(mon, " Auto filters:\n");
- for (f = usb_auto_filter; f; f = f->next) {
+ if (QTAILQ_EMPTY(&hostdevs))
+ return;
+ monitor_printf(mon, " Auto filters:\n");
+ QTAILQ_FOREACH(s, &hostdevs, next) {
char bus[10], addr[10], vid[10], pid[10];
+ f = &s->match;
dec2str(f->bus_num, bus, sizeof(bus));
dec2str(f->addr, addr, sizeof(addr));
hex2str(f->vendor_id, vid, sizeof(vid));
--
1.6.2.5
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [Qemu-devel] [PATCH 7/7] usb: print attached status in info qtree
2009-10-26 14:56 [Qemu-devel] [PATCH v2 0/7] use qdev for -usbdevice Gerd Hoffmann
` (5 preceding siblings ...)
2009-10-26 14:56 ` [Qemu-devel] [PATCH 6/7] usb-host: use qdev for -usbdevice + rework Gerd Hoffmann
@ 2009-10-26 14:56 ` Gerd Hoffmann
6 siblings, 0 replies; 8+ messages in thread
From: Gerd Hoffmann @ 2009-10-26 14:56 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
hw/usb-bus.c | 7 ++++---
1 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/hw/usb-bus.c b/hw/usb-bus.c
index 87dcc7f..99d185e 100644
--- a/hw/usb-bus.c
+++ b/hw/usb-bus.c
@@ -226,9 +226,10 @@ static void usb_bus_dev_print(Monitor *mon, DeviceState *qdev, int indent)
USBDevice *dev = DO_UPCAST(USBDevice, qdev, qdev);
USBBus *bus = usb_bus_from_device(dev);
- monitor_printf(mon, "%*saddr %d.%d, speed %s, name %s\n", indent, "",
- bus->busnr, dev->addr,
- usb_speed(dev->speed), dev->devname);
+ monitor_printf(mon, "%*saddr %d.%d, speed %s, name %s%s\n",
+ indent, "", bus->busnr, dev->addr,
+ usb_speed(dev->speed), dev->devname,
+ dev->attached ? ", attached" : "");
}
void usb_info(Monitor *mon)
--
1.6.2.5
^ permalink raw reply related [flat|nested] 8+ messages in thread