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 blkconf_blocksizes(&s->conf); 615 616 /* 617 * Hack alert: this pretends to be a block device, but it's really 618 * a SCSI bus that can serve only a single device, which it 619 * creates automatically. But first it needs to detach from its 620 * blockdev, or else scsi_bus_legacy_add_drive() dies when it 621 * attaches again. 622 * 623 * The hack is probably a bad idea. 624 */ 625 blk_detach_dev(blk, &s->dev.qdev); 626 s->conf.blk = NULL; 627 628 usb_desc_create_serial(dev); 629 usb_desc_init(dev); 630 scsi_bus_new(&s->bus, sizeof(s->bus), DEVICE(dev), 631 &usb_msd_scsi_info_storage, NULL); 632 scsi_dev = scsi_bus_legacy_add_drive(&s->bus, blk, 0, !!s->removable, 633 s->conf.bootindex, dev->serial, 634 &err); 635 if (!scsi_dev) { 636 error_propagate(errp, err); 637 return; 638 } 639 usb_msd_handle_reset(dev); 640 s->scsi_dev = scsi_dev; 641 642 if (bdrv_key_required(blk_bs(blk))) { 643 if (cur_mon) { 644 monitor_read_bdrv_key_start(cur_mon, blk_bs(blk), 645 usb_msd_password_cb, s); 646 s->dev.auto_attach = 0; 647 } else { 648 autostart = 0; 649 } 650 } 651 } 652 653 static void usb_msd_realize_bot(USBDevice *dev, Error **errp) 654 { 655 MSDState *s = DO_UPCAST(MSDState, dev, dev); 656 657 usb_desc_create_serial(dev); 658 usb_desc_init(dev); 659 scsi_bus_new(&s->bus, sizeof(s->bus), DEVICE(dev), 660 &usb_msd_scsi_info_bot, NULL); 661 usb_msd_handle_reset(dev); 662 } 663 664 static USBDevice *usb_msd_init(USBBus *bus, const char *filename) 665 { 666 static int nr=0; 667 Error *err = NULL; 668 char id[8]; 669 QemuOpts *opts; 670 DriveInfo *dinfo; 671 USBDevice *dev; 672 const char *p1; 673 char fmt[32]; 674 675 /* parse -usbdevice disk: syntax into drive opts */ 676 do { 677 snprintf(id, sizeof(id), "usb%d", nr++); 678 opts = qemu_opts_create(qemu_find_opts("drive"), id, 1, NULL); 679 } while (!opts); 680 681 p1 = strchr(filename, ':'); 682 if (p1++) { 683 const char *p2; 684 685 if (strstart(filename, "format=", &p2)) { 686 int len = MIN(p1 - p2, sizeof(fmt)); 687 pstrcpy(fmt, len, p2); 688 qemu_opt_set(opts, "format", fmt, &error_abort); 689 } else if (*filename != ':') { 690 error_report("unrecognized USB mass-storage option %s", filename); 691 return NULL; 692 } 693 filename = p1; 694 } 695 if (!*filename) { 696 error_report("block device specification needed"); 697 return NULL; 698 } 699 qemu_opt_set(opts, "file", filename, &error_abort); 700 qemu_opt_set(opts, "if", "none", &error_abort); 701 702 /* create host drive */ 703 dinfo = drive_new(opts, 0); 704 if (!dinfo) { 705 qemu_opts_del(opts); 706 return NULL; 707 } 708 709 /* create guest device */ 710 dev = usb_create(bus, "usb-storage"); 711 qdev_prop_set_drive(&dev->qdev, "drive", blk_by_legacy_dinfo(dinfo), 712 &err); 713 if (err) { 714 error_report_err(err); 715 object_unparent(OBJECT(dev)); 716 return NULL; 717 } 718 return dev; 719 } 720 721 static const VMStateDescription vmstate_usb_msd = { 722 .name = "usb-storage", 723 .version_id = 1, 724 .minimum_version_id = 1, 725 .fields = (VMStateField[]) { 726 VMSTATE_USB_DEVICE(dev, MSDState), 727 VMSTATE_UINT32(mode, MSDState), 728 VMSTATE_UINT32(scsi_len, MSDState), 729 VMSTATE_UINT32(scsi_off, MSDState), 730 VMSTATE_UINT32(data_len, MSDState), 731 VMSTATE_UINT32(csw.sig, MSDState), 732 VMSTATE_UINT32(csw.tag, MSDState), 733 VMSTATE_UINT32(csw.residue, MSDState), 734 VMSTATE_UINT8(csw.status, MSDState), 735 VMSTATE_END_OF_LIST() 736 } 737 }; 738 739 static Property msd_properties[] = { 740 DEFINE_BLOCK_PROPERTIES(MSDState, conf), 741 DEFINE_PROP_BIT("removable", MSDState, removable, 0, false), 742 DEFINE_PROP_END_OF_LIST(), 743 }; 744 745 static void usb_msd_class_initfn_common(ObjectClass *klass) 746 { 747 DeviceClass *dc = DEVICE_CLASS(klass); 748 USBDeviceClass *uc = USB_DEVICE_CLASS(klass); 749 750 uc->product_desc = "QEMU USB MSD"; 751 uc->usb_desc = &desc; 752 uc->cancel_packet = usb_msd_cancel_io; 753 uc->handle_attach = usb_desc_attach; 754 uc->handle_reset = usb_msd_handle_reset; 755 uc->handle_control = usb_msd_handle_control; 756 uc->handle_data = usb_msd_handle_data; 757 set_bit(DEVICE_CATEGORY_STORAGE, dc->categories); 758 dc->fw_name = "storage"; 759 dc->vmsd = &vmstate_usb_msd; 760 } 761 762 static void usb_msd_class_initfn_storage(ObjectClass *klass, void *data) 763 { 764 DeviceClass *dc = DEVICE_CLASS(klass); 765 USBDeviceClass *uc = USB_DEVICE_CLASS(klass); 766 767 uc->realize = usb_msd_realize_storage; 768 dc->props = msd_properties; 769 usb_msd_class_initfn_common(klass); 770 } 771 772 static void usb_msd_get_bootindex(Object *obj, Visitor *v, void *opaque, 773 const char *name, Error **errp) 774 { 775 USBDevice *dev = USB_DEVICE(obj); 776 MSDState *s = DO_UPCAST(MSDState, dev, dev); 777 778 visit_type_int32(v, &s->conf.bootindex, name, errp); 779 } 780 781 static void usb_msd_set_bootindex(Object *obj, Visitor *v, void *opaque, 782 const char *name, Error **errp) 783 { 784 USBDevice *dev = USB_DEVICE(obj); 785 MSDState *s = DO_UPCAST(MSDState, dev, dev); 786 int32_t boot_index; 787 Error *local_err = NULL; 788 789 visit_type_int32(v, &boot_index, name, &local_err); 790 if (local_err) { 791 goto out; 792 } 793 /* check whether bootindex is present in fw_boot_order list */ 794 check_boot_index(boot_index, &local_err); 795 if (local_err) { 796 goto out; 797 } 798 /* change bootindex to a new one */ 799 s->conf.bootindex = boot_index; 800 801 if (s->scsi_dev) { 802 object_property_set_int(OBJECT(s->scsi_dev), boot_index, "bootindex", 803 &error_abort); 804 } 805 806 out: 807 if (local_err) { 808 error_propagate(errp, local_err); 809 } 810 } 811 812 static void usb_msd_instance_init(Object *obj) 813 { 814 object_property_add(obj, "bootindex", "int32", 815 usb_msd_get_bootindex, 816 usb_msd_set_bootindex, NULL, NULL, NULL); 817 object_property_set_int(obj, -1, "bootindex", NULL); 818 } 819 820 static void usb_msd_class_initfn_bot(ObjectClass *klass, void *data) 821 { 822 USBDeviceClass *uc = USB_DEVICE_CLASS(klass); 823 DeviceClass *dc = DEVICE_CLASS(klass); 824 825 uc->realize = usb_msd_realize_bot; 826 usb_msd_class_initfn_common(klass); 827 dc->hotpluggable = false; 828 } 829 830 static const TypeInfo msd_info = { 831 .name = "usb-storage", 832 .parent = TYPE_USB_DEVICE, 833 .instance_size = sizeof(MSDState), 834 .class_init = usb_msd_class_initfn_storage, 835 .instance_init = usb_msd_instance_init, 836 }; 837 838 static const TypeInfo bot_info = { 839 .name = "usb-bot", 840 .parent = TYPE_USB_DEVICE, 841 .instance_size = sizeof(MSDState), 842 .class_init = usb_msd_class_initfn_bot, 843 }; 844 845 static void usb_msd_register_types(void) 846 { 847 type_register_static(&msd_info); 848 type_register_static(&bot_info); 849 usb_legacy_register("usb-storage", "disk", usb_msd_init); 850 } 851 852 type_init(usb_msd_register_types) 853