xref: /openbmc/qemu/hw/usb/dev-storage.c (revision 8fa3b702)
1 /*
2  * USB Mass Storage Device emulation
3  *
4  * Copyright (c) 2006 CodeSourcery.
5  * Written by Paul Brook
6  *
7  * This code is licensed under the LGPL.
8  */
9 
10 #include "qemu/osdep.h"
11 #include "qapi/error.h"
12 #include "qemu/error-report.h"
13 #include "qemu/module.h"
14 #include "qemu/option.h"
15 #include "qemu/config-file.h"
16 #include "hw/usb.h"
17 #include "desc.h"
18 #include "hw/qdev-properties.h"
19 #include "hw/scsi/scsi.h"
20 #include "migration/vmstate.h"
21 #include "sysemu/sysemu.h"
22 #include "sysemu/block-backend.h"
23 #include "qapi/visitor.h"
24 #include "qemu/cutils.h"
25 #include "qom/object.h"
26 
27 //#define DEBUG_MSD
28 
29 #ifdef DEBUG_MSD
30 #define DPRINTF(fmt, ...) \
31 do { printf("usb-msd: " fmt , ## __VA_ARGS__); } while (0)
32 #else
33 #define DPRINTF(fmt, ...) do {} while(0)
34 #endif
35 
36 /* USB requests.  */
37 #define MassStorageReset  0xff
38 #define GetMaxLun         0xfe
39 
40 enum USBMSDMode {
41     USB_MSDM_CBW, /* Command Block.  */
42     USB_MSDM_DATAOUT, /* Transfer data to device.  */
43     USB_MSDM_DATAIN, /* Transfer data from device.  */
44     USB_MSDM_CSW /* Command Status.  */
45 };
46 
47 struct usb_msd_csw {
48     uint32_t sig;
49     uint32_t tag;
50     uint32_t residue;
51     uint8_t status;
52 };
53 
54 struct MSDState {
55     USBDevice dev;
56     enum USBMSDMode mode;
57     uint32_t scsi_off;
58     uint32_t scsi_len;
59     uint32_t data_len;
60     struct usb_msd_csw csw;
61     SCSIRequest *req;
62     SCSIBus bus;
63     /* For async completion.  */
64     USBPacket *packet;
65     /* usb-storage only */
66     BlockConf conf;
67     uint32_t removable;
68     SCSIDevice *scsi_dev;
69 };
70 typedef struct MSDState MSDState;
71 
72 #define TYPE_USB_STORAGE "usb-storage-dev"
73 DECLARE_INSTANCE_CHECKER(MSDState, USB_STORAGE_DEV,
74                          TYPE_USB_STORAGE)
75 
76 struct usb_msd_cbw {
77     uint32_t sig;
78     uint32_t tag;
79     uint32_t data_len;
80     uint8_t flags;
81     uint8_t lun;
82     uint8_t cmd_len;
83     uint8_t cmd[16];
84 };
85 
86 enum {
87     STR_MANUFACTURER = 1,
88     STR_PRODUCT,
89     STR_SERIALNUMBER,
90     STR_CONFIG_FULL,
91     STR_CONFIG_HIGH,
92     STR_CONFIG_SUPER,
93 };
94 
95 static const USBDescStrings desc_strings = {
96     [STR_MANUFACTURER] = "QEMU",
97     [STR_PRODUCT]      = "QEMU USB HARDDRIVE",
98     [STR_SERIALNUMBER] = "1",
99     [STR_CONFIG_FULL]  = "Full speed config (usb 1.1)",
100     [STR_CONFIG_HIGH]  = "High speed config (usb 2.0)",
101     [STR_CONFIG_SUPER] = "Super speed config (usb 3.0)",
102 };
103 
104 static const USBDescIface desc_iface_full = {
105     .bInterfaceNumber              = 0,
106     .bNumEndpoints                 = 2,
107     .bInterfaceClass               = USB_CLASS_MASS_STORAGE,
108     .bInterfaceSubClass            = 0x06, /* SCSI */
109     .bInterfaceProtocol            = 0x50, /* Bulk */
110     .eps = (USBDescEndpoint[]) {
111         {
112             .bEndpointAddress      = USB_DIR_IN | 0x01,
113             .bmAttributes          = USB_ENDPOINT_XFER_BULK,
114             .wMaxPacketSize        = 64,
115         },{
116             .bEndpointAddress      = USB_DIR_OUT | 0x02,
117             .bmAttributes          = USB_ENDPOINT_XFER_BULK,
118             .wMaxPacketSize        = 64,
119         },
120     }
121 };
122 
123 static const USBDescDevice desc_device_full = {
124     .bcdUSB                        = 0x0200,
125     .bMaxPacketSize0               = 8,
126     .bNumConfigurations            = 1,
127     .confs = (USBDescConfig[]) {
128         {
129             .bNumInterfaces        = 1,
130             .bConfigurationValue   = 1,
131             .iConfiguration        = STR_CONFIG_FULL,
132             .bmAttributes          = USB_CFG_ATT_ONE | USB_CFG_ATT_SELFPOWER,
133             .nif = 1,
134             .ifs = &desc_iface_full,
135         },
136     },
137 };
138 
139 static const USBDescIface desc_iface_high = {
140     .bInterfaceNumber              = 0,
141     .bNumEndpoints                 = 2,
142     .bInterfaceClass               = USB_CLASS_MASS_STORAGE,
143     .bInterfaceSubClass            = 0x06, /* SCSI */
144     .bInterfaceProtocol            = 0x50, /* Bulk */
145     .eps = (USBDescEndpoint[]) {
146         {
147             .bEndpointAddress      = USB_DIR_IN | 0x01,
148             .bmAttributes          = USB_ENDPOINT_XFER_BULK,
149             .wMaxPacketSize        = 512,
150         },{
151             .bEndpointAddress      = USB_DIR_OUT | 0x02,
152             .bmAttributes          = USB_ENDPOINT_XFER_BULK,
153             .wMaxPacketSize        = 512,
154         },
155     }
156 };
157 
158 static const USBDescDevice desc_device_high = {
159     .bcdUSB                        = 0x0200,
160     .bMaxPacketSize0               = 64,
161     .bNumConfigurations            = 1,
162     .confs = (USBDescConfig[]) {
163         {
164             .bNumInterfaces        = 1,
165             .bConfigurationValue   = 1,
166             .iConfiguration        = STR_CONFIG_HIGH,
167             .bmAttributes          = USB_CFG_ATT_ONE | USB_CFG_ATT_SELFPOWER,
168             .nif = 1,
169             .ifs = &desc_iface_high,
170         },
171     },
172 };
173 
174 static const USBDescIface desc_iface_super = {
175     .bInterfaceNumber              = 0,
176     .bNumEndpoints                 = 2,
177     .bInterfaceClass               = USB_CLASS_MASS_STORAGE,
178     .bInterfaceSubClass            = 0x06, /* SCSI */
179     .bInterfaceProtocol            = 0x50, /* Bulk */
180     .eps = (USBDescEndpoint[]) {
181         {
182             .bEndpointAddress      = USB_DIR_IN | 0x01,
183             .bmAttributes          = USB_ENDPOINT_XFER_BULK,
184             .wMaxPacketSize        = 1024,
185             .bMaxBurst             = 15,
186         },{
187             .bEndpointAddress      = USB_DIR_OUT | 0x02,
188             .bmAttributes          = USB_ENDPOINT_XFER_BULK,
189             .wMaxPacketSize        = 1024,
190             .bMaxBurst             = 15,
191         },
192     }
193 };
194 
195 static const USBDescDevice desc_device_super = {
196     .bcdUSB                        = 0x0300,
197     .bMaxPacketSize0               = 9,
198     .bNumConfigurations            = 1,
199     .confs = (USBDescConfig[]) {
200         {
201             .bNumInterfaces        = 1,
202             .bConfigurationValue   = 1,
203             .iConfiguration        = STR_CONFIG_SUPER,
204             .bmAttributes          = USB_CFG_ATT_ONE | USB_CFG_ATT_SELFPOWER,
205             .nif = 1,
206             .ifs = &desc_iface_super,
207         },
208     },
209 };
210 
211 static const USBDesc desc = {
212     .id = {
213         .idVendor          = 0x46f4, /* CRC16() of "QEMU" */
214         .idProduct         = 0x0001,
215         .bcdDevice         = 0,
216         .iManufacturer     = STR_MANUFACTURER,
217         .iProduct          = STR_PRODUCT,
218         .iSerialNumber     = STR_SERIALNUMBER,
219     },
220     .full  = &desc_device_full,
221     .high  = &desc_device_high,
222     .super = &desc_device_super,
223     .str   = desc_strings,
224 };
225 
226 static void usb_msd_copy_data(MSDState *s, USBPacket *p)
227 {
228     uint32_t len;
229     len = p->iov.size - p->actual_length;
230     if (len > s->scsi_len)
231         len = s->scsi_len;
232     usb_packet_copy(p, scsi_req_get_buf(s->req) + s->scsi_off, len);
233     s->scsi_len -= len;
234     s->scsi_off += len;
235     if (len > s->data_len) {
236         len = s->data_len;
237     }
238     s->data_len -= len;
239     if (s->scsi_len == 0 || s->data_len == 0) {
240         scsi_req_continue(s->req);
241     }
242 }
243 
244 static void usb_msd_send_status(MSDState *s, USBPacket *p)
245 {
246     int len;
247 
248     DPRINTF("Command status %d tag 0x%x, len %zd\n",
249             s->csw.status, le32_to_cpu(s->csw.tag), p->iov.size);
250 
251     assert(s->csw.sig == cpu_to_le32(0x53425355));
252     len = MIN(sizeof(s->csw), p->iov.size);
253     usb_packet_copy(p, &s->csw, len);
254     memset(&s->csw, 0, sizeof(s->csw));
255 }
256 
257 static void usb_msd_packet_complete(MSDState *s)
258 {
259     USBPacket *p = s->packet;
260 
261     /* Set s->packet to NULL before calling usb_packet_complete
262        because another request may be issued before
263        usb_packet_complete returns.  */
264     DPRINTF("Packet complete %p\n", p);
265     s->packet = NULL;
266     usb_packet_complete(&s->dev, p);
267 }
268 
269 static void usb_msd_transfer_data(SCSIRequest *req, uint32_t len)
270 {
271     MSDState *s = DO_UPCAST(MSDState, dev.qdev, req->bus->qbus.parent);
272     USBPacket *p = s->packet;
273 
274     assert((s->mode == USB_MSDM_DATAOUT) == (req->cmd.mode == SCSI_XFER_TO_DEV));
275     s->scsi_len = len;
276     s->scsi_off = 0;
277     if (p) {
278         usb_msd_copy_data(s, p);
279         p = s->packet;
280         if (p && p->actual_length == p->iov.size) {
281             p->status = USB_RET_SUCCESS; /* Clear previous ASYNC status */
282             usb_msd_packet_complete(s);
283         }
284     }
285 }
286 
287 static void usb_msd_command_complete(SCSIRequest *req, uint32_t status, size_t resid)
288 {
289     MSDState *s = DO_UPCAST(MSDState, dev.qdev, req->bus->qbus.parent);
290     USBPacket *p = s->packet;
291 
292     DPRINTF("Command complete %d tag 0x%x\n", status, req->tag);
293 
294     s->csw.sig = cpu_to_le32(0x53425355);
295     s->csw.tag = cpu_to_le32(req->tag);
296     s->csw.residue = cpu_to_le32(s->data_len);
297     s->csw.status = status != 0;
298 
299     if (s->packet) {
300         if (s->data_len == 0 && s->mode == USB_MSDM_DATAOUT) {
301             /* A deferred packet with no write data remaining must be
302                the status read packet.  */
303             usb_msd_send_status(s, p);
304             s->mode = USB_MSDM_CBW;
305         } else if (s->mode == USB_MSDM_CSW) {
306             usb_msd_send_status(s, p);
307             s->mode = USB_MSDM_CBW;
308         } else {
309             if (s->data_len) {
310                 int len = (p->iov.size - p->actual_length);
311                 usb_packet_skip(p, len);
312                 if (len > s->data_len) {
313                     len = s->data_len;
314                 }
315                 s->data_len -= len;
316             }
317             if (s->data_len == 0) {
318                 s->mode = USB_MSDM_CSW;
319             }
320         }
321         p->status = USB_RET_SUCCESS; /* Clear previous ASYNC status */
322         usb_msd_packet_complete(s);
323     } else if (s->data_len == 0) {
324         s->mode = USB_MSDM_CSW;
325     }
326     scsi_req_unref(req);
327     s->req = NULL;
328 }
329 
330 static void usb_msd_request_cancelled(SCSIRequest *req)
331 {
332     MSDState *s = DO_UPCAST(MSDState, dev.qdev, req->bus->qbus.parent);
333 
334     if (req == s->req) {
335         scsi_req_unref(s->req);
336         s->req = NULL;
337         s->scsi_len = 0;
338     }
339 }
340 
341 static void usb_msd_handle_reset(USBDevice *dev)
342 {
343     MSDState *s = (MSDState *)dev;
344 
345     DPRINTF("Reset\n");
346     if (s->req) {
347         scsi_req_cancel(s->req);
348     }
349     assert(s->req == NULL);
350 
351     if (s->packet) {
352         s->packet->status = USB_RET_STALL;
353         usb_msd_packet_complete(s);
354     }
355 
356     s->mode = USB_MSDM_CBW;
357 }
358 
359 static void usb_msd_handle_control(USBDevice *dev, USBPacket *p,
360                int request, int value, int index, int length, uint8_t *data)
361 {
362     MSDState *s = (MSDState *)dev;
363     SCSIDevice *scsi_dev;
364     int ret, maxlun;
365 
366     ret = usb_desc_handle_control(dev, p, request, value, index, length, data);
367     if (ret >= 0) {
368         return;
369     }
370 
371     switch (request) {
372     case EndpointOutRequest | USB_REQ_CLEAR_FEATURE:
373         break;
374         /* Class specific requests.  */
375     case ClassInterfaceOutRequest | MassStorageReset:
376         /* Reset state ready for the next CBW.  */
377         s->mode = USB_MSDM_CBW;
378         break;
379     case ClassInterfaceRequest | GetMaxLun:
380         maxlun = 0;
381         for (;;) {
382             scsi_dev = scsi_device_find(&s->bus, 0, 0, maxlun+1);
383             if (scsi_dev == NULL) {
384                 break;
385             }
386             if (scsi_dev->lun != maxlun+1) {
387                 break;
388             }
389             maxlun++;
390         }
391         DPRINTF("MaxLun %d\n", maxlun);
392         data[0] = maxlun;
393         p->actual_length = 1;
394         break;
395     default:
396         p->status = USB_RET_STALL;
397         break;
398     }
399 }
400 
401 static void usb_msd_cancel_io(USBDevice *dev, USBPacket *p)
402 {
403     MSDState *s = USB_STORAGE_DEV(dev);
404 
405     assert(s->packet == p);
406     s->packet = NULL;
407 
408     if (s->req) {
409         scsi_req_cancel(s->req);
410     }
411 }
412 
413 static void usb_msd_handle_data(USBDevice *dev, USBPacket *p)
414 {
415     MSDState *s = (MSDState *)dev;
416     uint32_t tag;
417     struct usb_msd_cbw cbw;
418     uint8_t devep = p->ep->nr;
419     SCSIDevice *scsi_dev;
420     uint32_t len;
421 
422     switch (p->pid) {
423     case USB_TOKEN_OUT:
424         if (devep != 2)
425             goto fail;
426 
427         switch (s->mode) {
428         case USB_MSDM_CBW:
429             if (p->iov.size != 31) {
430                 error_report("usb-msd: Bad CBW size");
431                 goto fail;
432             }
433             usb_packet_copy(p, &cbw, 31);
434             if (le32_to_cpu(cbw.sig) != 0x43425355) {
435                 error_report("usb-msd: Bad signature %08x",
436                              le32_to_cpu(cbw.sig));
437                 goto fail;
438             }
439             DPRINTF("Command on LUN %d\n", cbw.lun);
440             scsi_dev = scsi_device_find(&s->bus, 0, 0, cbw.lun);
441             if (scsi_dev == NULL) {
442                 error_report("usb-msd: Bad LUN %d", cbw.lun);
443                 goto fail;
444             }
445             tag = le32_to_cpu(cbw.tag);
446             s->data_len = le32_to_cpu(cbw.data_len);
447             if (s->data_len == 0) {
448                 s->mode = USB_MSDM_CSW;
449             } else if (cbw.flags & 0x80) {
450                 s->mode = USB_MSDM_DATAIN;
451             } else {
452                 s->mode = USB_MSDM_DATAOUT;
453             }
454             DPRINTF("Command tag 0x%x flags %08x len %d data %d\n",
455                     tag, cbw.flags, cbw.cmd_len, s->data_len);
456             assert(le32_to_cpu(s->csw.residue) == 0);
457             s->scsi_len = 0;
458             s->req = scsi_req_new(scsi_dev, tag, cbw.lun, cbw.cmd, NULL);
459 #ifdef DEBUG_MSD
460             scsi_req_print(s->req);
461 #endif
462             len = scsi_req_enqueue(s->req);
463             if (len) {
464                 scsi_req_continue(s->req);
465             }
466             break;
467 
468         case USB_MSDM_DATAOUT:
469             DPRINTF("Data out %zd/%d\n", p->iov.size, s->data_len);
470             if (p->iov.size > s->data_len) {
471                 goto fail;
472             }
473 
474             if (s->scsi_len) {
475                 usb_msd_copy_data(s, p);
476             }
477             if (le32_to_cpu(s->csw.residue)) {
478                 int len = p->iov.size - p->actual_length;
479                 if (len) {
480                     usb_packet_skip(p, len);
481                     if (len > s->data_len) {
482                         len = s->data_len;
483                     }
484                     s->data_len -= len;
485                     if (s->data_len == 0) {
486                         s->mode = USB_MSDM_CSW;
487                     }
488                 }
489             }
490             if (p->actual_length < p->iov.size) {
491                 DPRINTF("Deferring packet %p [wait data-out]\n", p);
492                 s->packet = p;
493                 p->status = USB_RET_ASYNC;
494             }
495             break;
496 
497         default:
498             DPRINTF("Unexpected write (len %zd)\n", p->iov.size);
499             goto fail;
500         }
501         break;
502 
503     case USB_TOKEN_IN:
504         if (devep != 1)
505             goto fail;
506 
507         switch (s->mode) {
508         case USB_MSDM_DATAOUT:
509             if (s->data_len != 0 || p->iov.size < 13) {
510                 goto fail;
511             }
512             /* Waiting for SCSI write to complete.  */
513             s->packet = p;
514             p->status = USB_RET_ASYNC;
515             break;
516 
517         case USB_MSDM_CSW:
518             if (p->iov.size < 13) {
519                 goto fail;
520             }
521 
522             if (s->req) {
523                 /* still in flight */
524                 DPRINTF("Deferring packet %p [wait status]\n", p);
525                 s->packet = p;
526                 p->status = USB_RET_ASYNC;
527             } else {
528                 usb_msd_send_status(s, p);
529                 s->mode = USB_MSDM_CBW;
530             }
531             break;
532 
533         case USB_MSDM_DATAIN:
534             DPRINTF("Data in %zd/%d, scsi_len %d\n",
535                     p->iov.size, s->data_len, s->scsi_len);
536             if (s->scsi_len) {
537                 usb_msd_copy_data(s, p);
538             }
539             if (le32_to_cpu(s->csw.residue)) {
540                 int len = p->iov.size - p->actual_length;
541                 if (len) {
542                     usb_packet_skip(p, len);
543                     if (len > s->data_len) {
544                         len = s->data_len;
545                     }
546                     s->data_len -= len;
547                     if (s->data_len == 0) {
548                         s->mode = USB_MSDM_CSW;
549                     }
550                 }
551             }
552             if (p->actual_length < p->iov.size && s->mode == USB_MSDM_DATAIN) {
553                 DPRINTF("Deferring packet %p [wait data-in]\n", p);
554                 s->packet = p;
555                 p->status = USB_RET_ASYNC;
556             }
557             break;
558 
559         default:
560             DPRINTF("Unexpected read (len %zd)\n", p->iov.size);
561             goto fail;
562         }
563         break;
564 
565     default:
566         DPRINTF("Bad token\n");
567     fail:
568         p->status = USB_RET_STALL;
569         break;
570     }
571 }
572 
573 static void *usb_msd_load_request(QEMUFile *f, SCSIRequest *req)
574 {
575     MSDState *s = DO_UPCAST(MSDState, dev.qdev, req->bus->qbus.parent);
576 
577     /* nothing to load, just store req in our state struct */
578     assert(s->req == NULL);
579     scsi_req_ref(req);
580     s->req = req;
581     return NULL;
582 }
583 
584 static const struct SCSIBusInfo usb_msd_scsi_info_storage = {
585     .tcq = false,
586     .max_target = 0,
587     .max_lun = 0,
588 
589     .transfer_data = usb_msd_transfer_data,
590     .complete = usb_msd_command_complete,
591     .cancel = usb_msd_request_cancelled,
592     .load_request = usb_msd_load_request,
593 };
594 
595 static const struct SCSIBusInfo usb_msd_scsi_info_bot = {
596     .tcq = false,
597     .max_target = 0,
598     .max_lun = 15,
599 
600     .transfer_data = usb_msd_transfer_data,
601     .complete = usb_msd_command_complete,
602     .cancel = usb_msd_request_cancelled,
603     .load_request = usb_msd_load_request,
604 };
605 
606 static void usb_msd_storage_realize(USBDevice *dev, Error **errp)
607 {
608     MSDState *s = USB_STORAGE_DEV(dev);
609     BlockBackend *blk = s->conf.blk;
610     SCSIDevice *scsi_dev;
611 
612     if (!blk) {
613         error_setg(errp, "drive property not set");
614         return;
615     }
616 
617     if (!blkconf_blocksizes(&s->conf, errp)) {
618         return;
619     }
620 
621     if (!blkconf_apply_backend_options(&s->conf, blk_is_read_only(blk), true,
622                                        errp)) {
623         return;
624     }
625 
626     /*
627      * Hack alert: this pretends to be a block device, but it's really
628      * a SCSI bus that can serve only a single device, which it
629      * creates automatically.  But first it needs to detach from its
630      * blockdev, or else scsi_bus_legacy_add_drive() dies when it
631      * attaches again. We also need to take another reference so that
632      * blk_detach_dev() doesn't free blk while we still need it.
633      *
634      * The hack is probably a bad idea.
635      */
636     blk_ref(blk);
637     blk_detach_dev(blk, DEVICE(s));
638     s->conf.blk = NULL;
639 
640     usb_desc_create_serial(dev);
641     usb_desc_init(dev);
642     scsi_bus_new(&s->bus, sizeof(s->bus), DEVICE(dev),
643                  &usb_msd_scsi_info_storage, NULL);
644     scsi_dev = scsi_bus_legacy_add_drive(&s->bus, blk, 0, !!s->removable,
645                                          s->conf.bootindex, s->conf.share_rw,
646                                          s->conf.rerror, s->conf.werror,
647                                          dev->serial,
648                                          errp);
649     blk_unref(blk);
650     if (!scsi_dev) {
651         return;
652     }
653     usb_msd_handle_reset(dev);
654     s->scsi_dev = scsi_dev;
655 }
656 
657 static void usb_msd_bot_realize(USBDevice *dev, Error **errp)
658 {
659     MSDState *s = USB_STORAGE_DEV(dev);
660     DeviceState *d = DEVICE(dev);
661 
662     usb_desc_create_serial(dev);
663     usb_desc_init(dev);
664     if (d->hotplugged) {
665         s->dev.auto_attach = 0;
666     }
667 
668     scsi_bus_new(&s->bus, sizeof(s->bus), DEVICE(dev),
669                  &usb_msd_scsi_info_bot, NULL);
670     usb_msd_handle_reset(dev);
671 }
672 
673 static const VMStateDescription vmstate_usb_msd = {
674     .name = "usb-storage",
675     .version_id = 1,
676     .minimum_version_id = 1,
677     .fields = (VMStateField[]) {
678         VMSTATE_USB_DEVICE(dev, MSDState),
679         VMSTATE_UINT32(mode, MSDState),
680         VMSTATE_UINT32(scsi_len, MSDState),
681         VMSTATE_UINT32(scsi_off, MSDState),
682         VMSTATE_UINT32(data_len, MSDState),
683         VMSTATE_UINT32(csw.sig, MSDState),
684         VMSTATE_UINT32(csw.tag, MSDState),
685         VMSTATE_UINT32(csw.residue, MSDState),
686         VMSTATE_UINT8(csw.status, MSDState),
687         VMSTATE_END_OF_LIST()
688     }
689 };
690 
691 static Property msd_properties[] = {
692     DEFINE_BLOCK_PROPERTIES(MSDState, conf),
693     DEFINE_BLOCK_ERROR_PROPERTIES(MSDState, conf),
694     DEFINE_PROP_BIT("removable", MSDState, removable, 0, false),
695     DEFINE_PROP_END_OF_LIST(),
696 };
697 
698 static void usb_msd_class_initfn_common(ObjectClass *klass, void *data)
699 {
700     DeviceClass *dc = DEVICE_CLASS(klass);
701     USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
702 
703     uc->product_desc   = "QEMU USB MSD";
704     uc->usb_desc       = &desc;
705     uc->cancel_packet  = usb_msd_cancel_io;
706     uc->handle_attach  = usb_desc_attach;
707     uc->handle_reset   = usb_msd_handle_reset;
708     uc->handle_control = usb_msd_handle_control;
709     uc->handle_data    = usb_msd_handle_data;
710     set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
711     dc->fw_name = "storage";
712     dc->vmsd = &vmstate_usb_msd;
713 }
714 
715 static void usb_msd_class_storage_initfn(ObjectClass *klass, void *data)
716 {
717     DeviceClass *dc = DEVICE_CLASS(klass);
718     USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
719 
720     uc->realize = usb_msd_storage_realize;
721     device_class_set_props(dc, msd_properties);
722 }
723 
724 static void usb_msd_get_bootindex(Object *obj, Visitor *v, const char *name,
725                                   void *opaque, Error **errp)
726 {
727     USBDevice *dev = USB_DEVICE(obj);
728     MSDState *s = USB_STORAGE_DEV(dev);
729 
730     visit_type_int32(v, name, &s->conf.bootindex, errp);
731 }
732 
733 static void usb_msd_set_bootindex(Object *obj, Visitor *v, const char *name,
734                                   void *opaque, Error **errp)
735 {
736     USBDevice *dev = USB_DEVICE(obj);
737     MSDState *s = USB_STORAGE_DEV(dev);
738     int32_t boot_index;
739     Error *local_err = NULL;
740 
741     if (!visit_type_int32(v, name, &boot_index, errp)) {
742         return;
743     }
744     /* check whether bootindex is present in fw_boot_order list  */
745     check_boot_index(boot_index, &local_err);
746     if (local_err) {
747         goto out;
748     }
749     /* change bootindex to a new one */
750     s->conf.bootindex = boot_index;
751 
752     if (s->scsi_dev) {
753         object_property_set_int(OBJECT(s->scsi_dev), "bootindex", boot_index,
754                                 &error_abort);
755     }
756 
757 out:
758     error_propagate(errp, local_err);
759 }
760 
761 static const TypeInfo usb_storage_dev_type_info = {
762     .name = TYPE_USB_STORAGE,
763     .parent = TYPE_USB_DEVICE,
764     .instance_size = sizeof(MSDState),
765     .abstract = true,
766     .class_init = usb_msd_class_initfn_common,
767 };
768 
769 static void usb_msd_instance_init(Object *obj)
770 {
771     object_property_add(obj, "bootindex", "int32",
772                         usb_msd_get_bootindex,
773                         usb_msd_set_bootindex, NULL, NULL);
774     object_property_set_int(obj, "bootindex", -1, NULL);
775 }
776 
777 static void usb_msd_class_bot_initfn(ObjectClass *klass, void *data)
778 {
779     USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
780 
781     uc->realize = usb_msd_bot_realize;
782     uc->attached_settable = true;
783 }
784 
785 static const TypeInfo msd_info = {
786     .name          = "usb-storage",
787     .parent        = TYPE_USB_STORAGE,
788     .class_init    = usb_msd_class_storage_initfn,
789     .instance_init = usb_msd_instance_init,
790 };
791 
792 static const TypeInfo bot_info = {
793     .name          = "usb-bot",
794     .parent        = TYPE_USB_STORAGE,
795     .class_init    = usb_msd_class_bot_initfn,
796 };
797 
798 static void usb_msd_register_types(void)
799 {
800     type_register_static(&usb_storage_dev_type_info);
801     type_register_static(&msd_info);
802     type_register_static(&bot_info);
803 }
804 
805 type_init(usb_msd_register_types)
806