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