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