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