* See the COPYING file in the top-level directory.
*/
-#include "qemu-common.h"
+#include "qemu/osdep.h"
#include "qemu/option.h"
#include "qemu/config-file.h"
#include "trace.h"
+#include "qemu/error-report.h"
+#include "qemu/main-loop.h"
+#include "qemu/module.h"
#include "hw/usb.h"
-#include "hw/usb/desc.h"
+#include "migration/vmstate.h"
+#include "desc.h"
#include "hw/scsi/scsi.h"
-#include "block/scsi.h"
+#include "scsi/constants.h"
/* --------------------------------------------------------------------- */
USBPacket *status3[UAS_MAX_STREAMS + 1];
};
+#define TYPE_USB_UAS "usb-uas"
+#define USB_UAS(obj) OBJECT_CHECK(UASDevice, (obj), TYPE_USB_UAS)
+
struct UASRequest {
uint16_t tag;
uint64_t lun;
static void usb_uas_handle_reset(USBDevice *dev)
{
- UASDevice *uas = DO_UPCAST(UASDevice, dev, dev);
+ UASDevice *uas = USB_UAS(dev);
UASRequest *req, *nreq;
UASStatus *st, *nst;
if (ret >= 0) {
return;
}
- fprintf(stderr, "%s: unhandled control request\n", __func__);
+ error_report("%s: unhandled control request (req 0x%x, val 0x%x, idx 0x%x",
+ __func__, request, value, index);
p->status = USB_RET_STALL;
}
static void usb_uas_cancel_io(USBDevice *dev, USBPacket *p)
{
- UASDevice *uas = DO_UPCAST(UASDevice, dev, dev);
+ UASDevice *uas = USB_UAS(dev);
UASRequest *req, *nreq;
int i;
static void usb_uas_handle_data(USBDevice *dev, USBPacket *p)
{
- UASDevice *uas = DO_UPCAST(UASDevice, dev, dev);
+ UASDevice *uas = USB_UAS(dev);
uas_iu iu;
UASStatus *st;
UASRequest *req;
usb_uas_task(uas, &iu);
break;
default:
- fprintf(stderr, "%s: unknown command iu: id 0x%x\n",
- __func__, iu.hdr.id);
+ error_report("%s: unknown command iu: id 0x%x",
+ __func__, iu.hdr.id);
p->status = USB_RET_STALL;
break;
}
p->status = USB_RET_ASYNC;
break;
} else {
- fprintf(stderr, "%s: no inflight request\n", __func__);
+ error_report("%s: no inflight request", __func__);
p->status = USB_RET_STALL;
break;
}
usb_uas_start_next_transfer(uas);
break;
default:
- fprintf(stderr, "%s: invalid endpoint %d\n", __func__, p->ep->nr);
+ error_report("%s: invalid endpoint %d", __func__, p->ep->nr);
p->status = USB_RET_STALL;
break;
}
}
-static void usb_uas_handle_destroy(USBDevice *dev)
+static void usb_uas_unrealize(USBDevice *dev, Error **errp)
{
- UASDevice *uas = DO_UPCAST(UASDevice, dev, dev);
+ UASDevice *uas = USB_UAS(dev);
qemu_bh_delete(uas->status_bh);
}
-static int usb_uas_init(USBDevice *dev)
+static void usb_uas_realize(USBDevice *dev, Error **errp)
{
- UASDevice *uas = DO_UPCAST(UASDevice, dev, dev);
+ UASDevice *uas = USB_UAS(dev);
+ DeviceState *d = DEVICE(dev);
usb_desc_create_serial(dev);
usb_desc_init(dev);
+ if (d->hotplugged) {
+ uas->dev.auto_attach = 0;
+ }
QTAILQ_INIT(&uas->results);
QTAILQ_INIT(&uas->requests);
scsi_bus_new(&uas->bus, sizeof(uas->bus), DEVICE(dev),
&usb_uas_scsi_info, NULL);
-
- return 0;
}
static const VMStateDescription vmstate_usb_uas = {
DeviceClass *dc = DEVICE_CLASS(klass);
USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
- uc->init = usb_uas_init;
+ uc->realize = usb_uas_realize;
uc->product_desc = desc_strings[STR_PRODUCT];
uc->usb_desc = &desc;
uc->cancel_packet = usb_uas_cancel_io;
uc->handle_reset = usb_uas_handle_reset;
uc->handle_control = usb_uas_handle_control;
uc->handle_data = usb_uas_handle_data;
- uc->handle_destroy = usb_uas_handle_destroy;
+ uc->unrealize = usb_uas_unrealize;
+ uc->attached_settable = true;
set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
dc->fw_name = "storage";
dc->vmsd = &vmstate_usb_uas;
}
static const TypeInfo uas_info = {
- .name = "usb-uas",
+ .name = TYPE_USB_UAS,
.parent = TYPE_USB_DEVICE,
.instance_size = sizeof(UASDevice),
.class_init = usb_uas_class_initfn,