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