#include "hw/usb.h"
#include "hw/qdev.h"
#include "sysemu.h"
-#include "monitor.h"
+#include "monitor/monitor.h"
#include "trace.h"
static void usb_bus_dev_print(Monitor *mon, DeviceState *qdev, int indent);
DEFINE_PROP_END_OF_LIST()
};
-static struct BusInfo usb_bus_info = {
- .name = "USB",
- .size = sizeof(USBBus),
- .print_dev = usb_bus_dev_print,
- .get_dev_path = usb_get_dev_path,
- .get_fw_dev_path = usb_get_fw_dev_path,
- .props = usb_props,
+static void usb_bus_class_init(ObjectClass *klass, void *data)
+{
+ BusClass *k = BUS_CLASS(klass);
+
+ k->print_dev = usb_bus_dev_print;
+ k->get_dev_path = usb_get_dev_path;
+ k->get_fw_dev_path = usb_get_fw_dev_path;
+}
+
+static const TypeInfo usb_bus_info = {
+ .name = TYPE_USB_BUS,
+ .parent = TYPE_BUS,
+ .instance_size = sizeof(USBBus),
+ .class_init = usb_bus_class_init,
};
static int next_usb_bus = 0;
static QTAILQ_HEAD(, USBBus) busses = QTAILQ_HEAD_INITIALIZER(busses);
+static int usb_device_post_load(void *opaque, int version_id)
+{
+ USBDevice *dev = opaque;
+
+ if (dev->state == USB_STATE_NOTATTACHED) {
+ dev->attached = 0;
+ } else {
+ dev->attached = 1;
+ }
+ return 0;
+}
+
const VMStateDescription vmstate_usb_device = {
.name = "USBDevice",
.version_id = 1,
.minimum_version_id = 1,
+ .post_load = usb_device_post_load,
.fields = (VMStateField []) {
VMSTATE_UINT8(addr, USBDevice),
VMSTATE_INT32(state, USBDevice),
void usb_bus_new(USBBus *bus, USBBusOps *ops, DeviceState *host)
{
- qbus_create_inplace(&bus->qbus, &usb_bus_info, host, NULL);
+ qbus_create_inplace(&bus->qbus, TYPE_USB_BUS, host, NULL);
bus->ops = ops;
bus->busnr = next_usb_bus++;
bus->qbus.allow_hotplug = 1; /* Yes, we can */
}
}
-int usb_device_handle_control(USBDevice *dev, USBPacket *p, int request,
- int value, int index, int length, uint8_t *data)
+void usb_device_handle_control(USBDevice *dev, USBPacket *p, int request,
+ int value, int index, int length, uint8_t *data)
{
USBDeviceClass *klass = USB_DEVICE_GET_CLASS(dev);
if (klass->handle_control) {
- return klass->handle_control(dev, p, request, value, index, length,
- data);
+ klass->handle_control(dev, p, request, value, index, length, data);
}
- return -ENOSYS;
}
-int usb_device_handle_data(USBDevice *dev, USBPacket *p)
+void usb_device_handle_data(USBDevice *dev, USBPacket *p)
{
USBDeviceClass *klass = USB_DEVICE_GET_CLASS(dev);
if (klass->handle_data) {
- return klass->handle_data(dev, p);
+ klass->handle_data(dev, p);
}
- return -ENOSYS;
}
const char *usb_device_get_product_desc(USBDevice *dev)
const USBDesc *usb_device_get_usb_desc(USBDevice *dev)
{
USBDeviceClass *klass = USB_DEVICE_GET_CLASS(dev);
+ if (dev->usb_desc) {
+ return dev->usb_desc;
+ }
return klass->usb_desc;
}
}
}
+void usb_device_flush_ep_queue(USBDevice *dev, USBEndpoint *ep)
+{
+ USBDeviceClass *klass = USB_DEVICE_GET_CLASS(dev);
+ if (klass->flush_ep_queue) {
+ klass->flush_ep_queue(dev, ep);
+ }
+}
+
static int usb_qdev_init(DeviceState *qdev)
{
USBDevice *dev = USB_DEVICE(qdev);
DeviceState *hcd = qdev->parent_bus->parent;
char *id = NULL;
- if ((dev->flags & (1 << USB_DEV_FLAG_FULL_PATH)) &&
- hcd && hcd->parent_bus && hcd->parent_bus->info->get_dev_path) {
- id = hcd->parent_bus->info->get_dev_path(hcd);
+ if (dev->flags & (1 << USB_DEV_FLAG_FULL_PATH)) {
+ id = qdev_get_dev_path(hcd);
}
if (id) {
char *ret = g_strdup_printf("%s/%s", id, dev->port->path);
return NULL;
}
+ if (!bus) {
+ error_report("Error: no usb bus to attach usbdevice %s, "
+ "please try -machine usb=on and check that "
+ "the machine model supports USB", driver);
+ return NULL;
+ }
+
if (!f->usbdevice_init) {
if (*params) {
error_report("usbdevice %s accepts no params", driver);
static void usb_device_class_init(ObjectClass *klass, void *data)
{
DeviceClass *k = DEVICE_CLASS(klass);
- k->bus_info = &usb_bus_info;
+ k->bus_type = TYPE_USB_BUS;
k->init = usb_qdev_init;
k->unplug = qdev_simple_unplug_cb;
k->exit = usb_qdev_exit;
+ k->props = usb_props;
}
static TypeInfo usb_device_type_info = {
static void usb_register_types(void)
{
+ type_register_static(&usb_bus_info);
type_register_static(&usb_device_type_info);
}