131b7bed8SGerd Hoffmann /*
231b7bed8SGerd Hoffmann * USB Mass Storage Device emulation
331b7bed8SGerd Hoffmann *
431b7bed8SGerd Hoffmann * Copyright (c) 2006 CodeSourcery.
531b7bed8SGerd Hoffmann * Written by Paul Brook
631b7bed8SGerd Hoffmann *
731b7bed8SGerd Hoffmann * This code is licensed under the LGPL.
831b7bed8SGerd Hoffmann */
931b7bed8SGerd Hoffmann
1031b7bed8SGerd Hoffmann #include "qemu/osdep.h"
1131b7bed8SGerd Hoffmann #include "qapi/error.h"
1231b7bed8SGerd Hoffmann #include "hw/usb.h"
1331b7bed8SGerd Hoffmann #include "hw/usb/desc.h"
1431b7bed8SGerd Hoffmann #include "hw/usb/msd.h"
1531b7bed8SGerd Hoffmann
1631b7bed8SGerd Hoffmann static const struct SCSIBusInfo usb_msd_scsi_info_bot = {
1731b7bed8SGerd Hoffmann .tcq = false,
1831b7bed8SGerd Hoffmann .max_target = 0,
1931b7bed8SGerd Hoffmann .max_lun = 15,
2031b7bed8SGerd Hoffmann
2131b7bed8SGerd Hoffmann .transfer_data = usb_msd_transfer_data,
2231b7bed8SGerd Hoffmann .complete = usb_msd_command_complete,
2331b7bed8SGerd Hoffmann .cancel = usb_msd_request_cancelled,
2431b7bed8SGerd Hoffmann .load_request = usb_msd_load_request,
2531b7bed8SGerd Hoffmann };
2631b7bed8SGerd Hoffmann
usb_msd_bot_realize(USBDevice * dev,Error ** errp)2731b7bed8SGerd Hoffmann static void usb_msd_bot_realize(USBDevice *dev, Error **errp)
2831b7bed8SGerd Hoffmann {
2931b7bed8SGerd Hoffmann MSDState *s = USB_STORAGE_DEV(dev);
3031b7bed8SGerd Hoffmann DeviceState *d = DEVICE(dev);
3131b7bed8SGerd Hoffmann
3231b7bed8SGerd Hoffmann usb_desc_create_serial(dev);
3331b7bed8SGerd Hoffmann usb_desc_init(dev);
34b7b2a60bSGerd Hoffmann dev->flags |= (1 << USB_DEV_FLAG_IS_SCSI_STORAGE);
3531b7bed8SGerd Hoffmann if (d->hotplugged) {
3631b7bed8SGerd Hoffmann s->dev.auto_attach = 0;
3731b7bed8SGerd Hoffmann }
3831b7bed8SGerd Hoffmann
39*739e95f5SPeter Maydell scsi_bus_init(&s->bus, sizeof(s->bus), DEVICE(dev), &usb_msd_scsi_info_bot);
4031b7bed8SGerd Hoffmann usb_msd_handle_reset(dev);
4131b7bed8SGerd Hoffmann }
4231b7bed8SGerd Hoffmann
usb_msd_class_bot_initfn(ObjectClass * klass,void * data)4331b7bed8SGerd Hoffmann static void usb_msd_class_bot_initfn(ObjectClass *klass, void *data)
4431b7bed8SGerd Hoffmann {
4531b7bed8SGerd Hoffmann USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
4631b7bed8SGerd Hoffmann
4731b7bed8SGerd Hoffmann uc->realize = usb_msd_bot_realize;
4831b7bed8SGerd Hoffmann uc->attached_settable = true;
4931b7bed8SGerd Hoffmann }
5031b7bed8SGerd Hoffmann
5131b7bed8SGerd Hoffmann static const TypeInfo bot_info = {
5231b7bed8SGerd Hoffmann .name = "usb-bot",
5331b7bed8SGerd Hoffmann .parent = TYPE_USB_STORAGE,
5431b7bed8SGerd Hoffmann .class_init = usb_msd_class_bot_initfn,
5531b7bed8SGerd Hoffmann };
5631b7bed8SGerd Hoffmann
register_types(void)5731b7bed8SGerd Hoffmann static void register_types(void)
5831b7bed8SGerd Hoffmann {
5931b7bed8SGerd Hoffmann type_register_static(&bot_info);
6031b7bed8SGerd Hoffmann }
6131b7bed8SGerd Hoffmann
6231b7bed8SGerd Hoffmann type_init(register_types)
63