sdl: Properly mark modifier+u as hotkey
[qemu/mdroth.git] / hw / scsi-disk.c
blobfa198f928cdeb2ca9f2158a250300f8bf5234fc5
1 /*
2 * SCSI Device emulation
4 * Copyright (c) 2006 CodeSourcery.
5 * Based on code by Fabrice Bellard
7 * Written by Paul Brook
8 * Modifications:
9 * 2009-Dec-12 Artyom Tarasenko : implemented stamdard inquiry for the case
10 * when the allocation length of CDB is smaller
11 * than 36.
12 * 2009-Oct-13 Artyom Tarasenko : implemented the block descriptor in the
13 * MODE SENSE response.
15 * This code is licensed under the LGPL.
17 * Note that this file only handles the SCSI architecture model and device
18 * commands. Emulation of interface/link layer protocols is handled by
19 * the host adapter emulator.
22 //#define DEBUG_SCSI
24 #ifdef DEBUG_SCSI
25 #define DPRINTF(fmt, ...) \
26 do { printf("scsi-disk: " fmt , ## __VA_ARGS__); } while (0)
27 #else
28 #define DPRINTF(fmt, ...) do {} while(0)
29 #endif
31 #define BADF(fmt, ...) \
32 do { fprintf(stderr, "scsi-disk: " fmt , ## __VA_ARGS__); } while (0)
34 #include "qemu-common.h"
35 #include "qemu-error.h"
36 #include "scsi.h"
37 #include "scsi-defs.h"
38 #include "sysemu.h"
39 #include "blockdev.h"
41 #define SCSI_DMA_BUF_SIZE 131072
42 #define SCSI_MAX_INQUIRY_LEN 256
44 #define SCSI_REQ_STATUS_RETRY 0x01
45 #define SCSI_REQ_STATUS_RETRY_TYPE_MASK 0x06
46 #define SCSI_REQ_STATUS_RETRY_READ 0x00
47 #define SCSI_REQ_STATUS_RETRY_WRITE 0x02
48 #define SCSI_REQ_STATUS_RETRY_FLUSH 0x04
50 typedef struct SCSIDiskState SCSIDiskState;
52 typedef struct SCSIDiskReq {
53 SCSIRequest req;
54 /* Both sector and sector_count are in terms of qemu 512 byte blocks. */
55 uint64_t sector;
56 uint32_t sector_count;
57 struct iovec iov;
58 QEMUIOVector qiov;
59 uint32_t status;
60 } SCSIDiskReq;
62 struct SCSIDiskState
64 SCSIDevice qdev;
65 BlockDriverState *bs;
66 /* The qemu block layer uses a fixed 512 byte sector size.
67 This is the number of 512 byte blocks in a single scsi sector. */
68 int cluster_size;
69 uint32_t removable;
70 uint64_t max_lba;
71 QEMUBH *bh;
72 char *version;
73 char *serial;
74 SCSISense sense;
77 static int scsi_handle_rw_error(SCSIDiskReq *r, int error, int type);
78 static int scsi_disk_emulate_command(SCSIDiskReq *r, uint8_t *outbuf);
80 static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag,
81 uint32_t lun, void *hba_private)
83 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, d);
84 SCSIRequest *req;
85 SCSIDiskReq *r;
87 req = scsi_req_alloc(sizeof(SCSIDiskReq), &s->qdev, tag, lun, hba_private);
88 r = DO_UPCAST(SCSIDiskReq, req, req);
89 r->iov.iov_base = qemu_blockalign(s->bs, SCSI_DMA_BUF_SIZE);
90 return req;
93 static void scsi_free_request(SCSIRequest *req)
95 SCSIDiskReq *r = DO_UPCAST(SCSIDiskReq, req, req);
97 qemu_vfree(r->iov.iov_base);
100 static void scsi_disk_clear_sense(SCSIDiskState *s)
102 memset(&s->sense, 0, sizeof(s->sense));
105 static void scsi_req_set_status(SCSIDiskReq *r, int status, SCSISense sense)
107 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
109 r->req.status = status;
110 s->sense = sense;
113 /* Helper function for command completion. */
114 static void scsi_command_complete(SCSIDiskReq *r, int status, SCSISense sense)
116 DPRINTF("Command complete tag=0x%x status=%d sense=%d/%d/%d\n",
117 r->req.tag, status, sense.key, sense.asc, sense.ascq);
118 scsi_req_set_status(r, status, sense);
119 scsi_req_complete(&r->req);
122 /* Cancel a pending data transfer. */
123 static void scsi_cancel_io(SCSIRequest *req)
125 SCSIDiskReq *r = DO_UPCAST(SCSIDiskReq, req, req);
127 DPRINTF("Cancel tag=0x%x\n", req->tag);
128 if (r->req.aiocb) {
129 bdrv_aio_cancel(r->req.aiocb);
131 r->req.aiocb = NULL;
134 static void scsi_read_complete(void * opaque, int ret)
136 SCSIDiskReq *r = (SCSIDiskReq *)opaque;
137 int n;
139 r->req.aiocb = NULL;
141 if (ret) {
142 if (scsi_handle_rw_error(r, -ret, SCSI_REQ_STATUS_RETRY_READ)) {
143 return;
147 DPRINTF("Data ready tag=0x%x len=%zd\n", r->req.tag, r->iov.iov_len);
149 n = r->iov.iov_len / 512;
150 r->sector += n;
151 r->sector_count -= n;
152 scsi_req_data(&r->req, r->iov.iov_len);
156 /* Read more data from scsi device into buffer. */
157 static void scsi_read_data(SCSIRequest *req)
159 SCSIDiskReq *r = DO_UPCAST(SCSIDiskReq, req, req);
160 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
161 uint32_t n;
163 if (r->sector_count == (uint32_t)-1) {
164 DPRINTF("Read buf_len=%zd\n", r->iov.iov_len);
165 r->sector_count = 0;
166 scsi_req_data(&r->req, r->iov.iov_len);
167 return;
169 DPRINTF("Read sector_count=%d\n", r->sector_count);
170 if (r->sector_count == 0) {
171 scsi_command_complete(r, GOOD, SENSE_CODE(NO_SENSE));
172 return;
175 /* No data transfer may already be in progress */
176 assert(r->req.aiocb == NULL);
178 if (r->req.cmd.mode == SCSI_XFER_TO_DEV) {
179 DPRINTF("Data transfer direction invalid\n");
180 scsi_read_complete(r, -EINVAL);
181 return;
184 n = r->sector_count;
185 if (n > SCSI_DMA_BUF_SIZE / 512)
186 n = SCSI_DMA_BUF_SIZE / 512;
188 r->iov.iov_len = n * 512;
189 qemu_iovec_init_external(&r->qiov, &r->iov, 1);
190 r->req.aiocb = bdrv_aio_readv(s->bs, r->sector, &r->qiov, n,
191 scsi_read_complete, r);
192 if (r->req.aiocb == NULL) {
193 scsi_read_complete(r, -EIO);
197 static int scsi_handle_rw_error(SCSIDiskReq *r, int error, int type)
199 int is_read = (type == SCSI_REQ_STATUS_RETRY_READ);
200 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
201 BlockErrorAction action = bdrv_get_on_error(s->bs, is_read);
203 if (action == BLOCK_ERR_IGNORE) {
204 bdrv_mon_event(s->bs, BDRV_ACTION_IGNORE, is_read);
205 return 0;
208 if ((error == ENOSPC && action == BLOCK_ERR_STOP_ENOSPC)
209 || action == BLOCK_ERR_STOP_ANY) {
211 type &= SCSI_REQ_STATUS_RETRY_TYPE_MASK;
212 r->status |= SCSI_REQ_STATUS_RETRY | type;
214 bdrv_mon_event(s->bs, BDRV_ACTION_STOP, is_read);
215 vm_stop(VMSTOP_DISKFULL);
216 } else {
217 if (type == SCSI_REQ_STATUS_RETRY_READ) {
218 scsi_req_data(&r->req, 0);
220 switch (error) {
221 case ENOMEM:
222 scsi_command_complete(r, CHECK_CONDITION,
223 SENSE_CODE(TARGET_FAILURE));
224 break;
225 case EINVAL:
226 scsi_command_complete(r, CHECK_CONDITION,
227 SENSE_CODE(INVALID_FIELD));
228 break;
229 default:
230 scsi_command_complete(r, CHECK_CONDITION,
231 SENSE_CODE(IO_ERROR));
232 break;
234 bdrv_mon_event(s->bs, BDRV_ACTION_REPORT, is_read);
236 return 1;
239 static void scsi_write_complete(void * opaque, int ret)
241 SCSIDiskReq *r = (SCSIDiskReq *)opaque;
242 uint32_t len;
243 uint32_t n;
245 r->req.aiocb = NULL;
247 if (ret) {
248 if (scsi_handle_rw_error(r, -ret, SCSI_REQ_STATUS_RETRY_WRITE)) {
249 return;
253 n = r->iov.iov_len / 512;
254 r->sector += n;
255 r->sector_count -= n;
256 if (r->sector_count == 0) {
257 scsi_command_complete(r, GOOD, SENSE_CODE(NO_SENSE));
258 } else {
259 len = r->sector_count * 512;
260 if (len > SCSI_DMA_BUF_SIZE) {
261 len = SCSI_DMA_BUF_SIZE;
263 r->iov.iov_len = len;
264 DPRINTF("Write complete tag=0x%x more=%d\n", r->req.tag, len);
265 scsi_req_data(&r->req, len);
269 static void scsi_write_data(SCSIRequest *req)
271 SCSIDiskReq *r = DO_UPCAST(SCSIDiskReq, req, req);
272 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
273 uint32_t n;
275 /* No data transfer may already be in progress */
276 assert(r->req.aiocb == NULL);
278 if (r->req.cmd.mode != SCSI_XFER_TO_DEV) {
279 DPRINTF("Data transfer direction invalid\n");
280 scsi_write_complete(r, -EINVAL);
281 return;
284 n = r->iov.iov_len / 512;
285 if (n) {
286 qemu_iovec_init_external(&r->qiov, &r->iov, 1);
287 r->req.aiocb = bdrv_aio_writev(s->bs, r->sector, &r->qiov, n,
288 scsi_write_complete, r);
289 if (r->req.aiocb == NULL) {
290 scsi_write_complete(r, -ENOMEM);
292 } else {
293 /* Invoke completion routine to fetch data from host. */
294 scsi_write_complete(r, 0);
298 static void scsi_dma_restart_bh(void *opaque)
300 SCSIDiskState *s = opaque;
301 SCSIRequest *req;
302 SCSIDiskReq *r;
304 qemu_bh_delete(s->bh);
305 s->bh = NULL;
307 QTAILQ_FOREACH(req, &s->qdev.requests, next) {
308 r = DO_UPCAST(SCSIDiskReq, req, req);
309 if (r->status & SCSI_REQ_STATUS_RETRY) {
310 int status = r->status;
311 int ret;
313 r->status &=
314 ~(SCSI_REQ_STATUS_RETRY | SCSI_REQ_STATUS_RETRY_TYPE_MASK);
316 switch (status & SCSI_REQ_STATUS_RETRY_TYPE_MASK) {
317 case SCSI_REQ_STATUS_RETRY_READ:
318 scsi_read_data(&r->req);
319 break;
320 case SCSI_REQ_STATUS_RETRY_WRITE:
321 scsi_write_data(&r->req);
322 break;
323 case SCSI_REQ_STATUS_RETRY_FLUSH:
324 ret = scsi_disk_emulate_command(r, r->iov.iov_base);
325 if (ret == 0) {
326 scsi_command_complete(r, GOOD, SENSE_CODE(NO_SENSE));
333 static void scsi_dma_restart_cb(void *opaque, int running, int reason)
335 SCSIDiskState *s = opaque;
337 if (!running)
338 return;
340 if (!s->bh) {
341 s->bh = qemu_bh_new(scsi_dma_restart_bh, s);
342 qemu_bh_schedule(s->bh);
346 /* Return a pointer to the data buffer. */
347 static uint8_t *scsi_get_buf(SCSIRequest *req)
349 SCSIDiskReq *r = DO_UPCAST(SCSIDiskReq, req, req);
351 return (uint8_t *)r->iov.iov_base;
354 /* Copy sense information into the provided buffer */
355 static int scsi_get_sense(SCSIRequest *req, uint8_t *outbuf, int len)
357 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev);
359 return scsi_build_sense(s->sense, outbuf, len, len > 14);
362 static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf)
364 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev);
365 int buflen = 0;
367 if (req->cmd.buf[1] & 0x2) {
368 /* Command support data - optional, not implemented */
369 BADF("optional INQUIRY command support request not implemented\n");
370 return -1;
373 if (req->cmd.buf[1] & 0x1) {
374 /* Vital product data */
375 uint8_t page_code = req->cmd.buf[2];
376 if (req->cmd.xfer < 4) {
377 BADF("Error: Inquiry (EVPD[%02X]) buffer size %zd is "
378 "less than 4\n", page_code, req->cmd.xfer);
379 return -1;
382 if (s->qdev.type == TYPE_ROM) {
383 outbuf[buflen++] = 5;
384 } else {
385 outbuf[buflen++] = 0;
387 outbuf[buflen++] = page_code ; // this page
388 outbuf[buflen++] = 0x00;
390 switch (page_code) {
391 case 0x00: /* Supported page codes, mandatory */
393 int pages;
394 DPRINTF("Inquiry EVPD[Supported pages] "
395 "buffer size %zd\n", req->cmd.xfer);
396 pages = buflen++;
397 outbuf[buflen++] = 0x00; // list of supported pages (this page)
398 if (s->serial)
399 outbuf[buflen++] = 0x80; // unit serial number
400 outbuf[buflen++] = 0x83; // device identification
401 if (s->qdev.type == TYPE_DISK) {
402 outbuf[buflen++] = 0xb0; // block limits
403 outbuf[buflen++] = 0xb2; // thin provisioning
405 outbuf[pages] = buflen - pages - 1; // number of pages
406 break;
408 case 0x80: /* Device serial number, optional */
410 int l;
412 if (!s->serial) {
413 DPRINTF("Inquiry (EVPD[Serial number] not supported\n");
414 return -1;
417 l = strlen(s->serial);
418 if (l > req->cmd.xfer)
419 l = req->cmd.xfer;
420 if (l > 20)
421 l = 20;
423 DPRINTF("Inquiry EVPD[Serial number] "
424 "buffer size %zd\n", req->cmd.xfer);
425 outbuf[buflen++] = l;
426 memcpy(outbuf+buflen, s->serial, l);
427 buflen += l;
428 break;
431 case 0x83: /* Device identification page, mandatory */
433 int max_len = 255 - 8;
434 int id_len = strlen(bdrv_get_device_name(s->bs));
436 if (id_len > max_len)
437 id_len = max_len;
438 DPRINTF("Inquiry EVPD[Device identification] "
439 "buffer size %zd\n", req->cmd.xfer);
441 outbuf[buflen++] = 4 + id_len;
442 outbuf[buflen++] = 0x2; // ASCII
443 outbuf[buflen++] = 0; // not officially assigned
444 outbuf[buflen++] = 0; // reserved
445 outbuf[buflen++] = id_len; // length of data following
447 memcpy(outbuf+buflen, bdrv_get_device_name(s->bs), id_len);
448 buflen += id_len;
449 break;
451 case 0xb0: /* block limits */
453 unsigned int unmap_sectors =
454 s->qdev.conf.discard_granularity / s->qdev.blocksize;
455 unsigned int min_io_size =
456 s->qdev.conf.min_io_size / s->qdev.blocksize;
457 unsigned int opt_io_size =
458 s->qdev.conf.opt_io_size / s->qdev.blocksize;
460 if (s->qdev.type == TYPE_ROM) {
461 DPRINTF("Inquiry (EVPD[%02X] not supported for CDROM\n",
462 page_code);
463 return -1;
465 /* required VPD size with unmap support */
466 outbuf[3] = buflen = 0x3c;
468 memset(outbuf + 4, 0, buflen - 4);
470 /* optimal transfer length granularity */
471 outbuf[6] = (min_io_size >> 8) & 0xff;
472 outbuf[7] = min_io_size & 0xff;
474 /* optimal transfer length */
475 outbuf[12] = (opt_io_size >> 24) & 0xff;
476 outbuf[13] = (opt_io_size >> 16) & 0xff;
477 outbuf[14] = (opt_io_size >> 8) & 0xff;
478 outbuf[15] = opt_io_size & 0xff;
480 /* optimal unmap granularity */
481 outbuf[28] = (unmap_sectors >> 24) & 0xff;
482 outbuf[29] = (unmap_sectors >> 16) & 0xff;
483 outbuf[30] = (unmap_sectors >> 8) & 0xff;
484 outbuf[31] = unmap_sectors & 0xff;
485 break;
487 case 0xb2: /* thin provisioning */
489 outbuf[3] = buflen = 8;
490 outbuf[4] = 0;
491 outbuf[5] = 0x40; /* write same with unmap supported */
492 outbuf[6] = 0;
493 outbuf[7] = 0;
494 break;
496 default:
497 BADF("Error: unsupported Inquiry (EVPD[%02X]) "
498 "buffer size %zd\n", page_code, req->cmd.xfer);
499 return -1;
501 /* done with EVPD */
502 return buflen;
505 /* Standard INQUIRY data */
506 if (req->cmd.buf[2] != 0) {
507 BADF("Error: Inquiry (STANDARD) page or code "
508 "is non-zero [%02X]\n", req->cmd.buf[2]);
509 return -1;
512 /* PAGE CODE == 0 */
513 if (req->cmd.xfer < 5) {
514 BADF("Error: Inquiry (STANDARD) buffer size %zd "
515 "is less than 5\n", req->cmd.xfer);
516 return -1;
519 buflen = req->cmd.xfer;
520 if (buflen > SCSI_MAX_INQUIRY_LEN)
521 buflen = SCSI_MAX_INQUIRY_LEN;
523 memset(outbuf, 0, buflen);
525 if (req->lun) {
526 outbuf[0] = 0x7f; /* LUN not supported */
527 return buflen;
530 outbuf[0] = s->qdev.type & 0x1f;
531 if (s->qdev.type == TYPE_ROM) {
532 outbuf[1] = 0x80;
533 memcpy(&outbuf[16], "QEMU CD-ROM ", 16);
534 } else {
535 outbuf[1] = s->removable ? 0x80 : 0;
536 memcpy(&outbuf[16], "QEMU HARDDISK ", 16);
538 memcpy(&outbuf[8], "QEMU ", 8);
539 memset(&outbuf[32], 0, 4);
540 memcpy(&outbuf[32], s->version, MIN(4, strlen(s->version)));
542 * We claim conformance to SPC-3, which is required for guests
543 * to ask for modern features like READ CAPACITY(16) or the
544 * block characteristics VPD page by default. Not all of SPC-3
545 * is actually implemented, but we're good enough.
547 outbuf[2] = 5;
548 outbuf[3] = 2; /* Format 2 */
550 if (buflen > 36) {
551 outbuf[4] = buflen - 5; /* Additional Length = (Len - 1) - 4 */
552 } else {
553 /* If the allocation length of CDB is too small,
554 the additional length is not adjusted */
555 outbuf[4] = 36 - 5;
558 /* Sync data transfer and TCQ. */
559 outbuf[7] = 0x10 | (req->bus->tcq ? 0x02 : 0);
560 return buflen;
563 static int mode_sense_page(SCSIRequest *req, int page, uint8_t *p,
564 int page_control)
566 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev);
567 BlockDriverState *bdrv = s->bs;
568 int cylinders, heads, secs;
571 * If Changeable Values are requested, a mask denoting those mode parameters
572 * that are changeable shall be returned. As we currently don't support
573 * parameter changes via MODE_SELECT all bits are returned set to zero.
574 * The buffer was already menset to zero by the caller of this function.
576 switch (page) {
577 case 4: /* Rigid disk device geometry page. */
578 p[0] = 4;
579 p[1] = 0x16;
580 if (page_control == 1) { /* Changeable Values */
581 return p[1] + 2;
583 /* if a geometry hint is available, use it */
584 bdrv_get_geometry_hint(bdrv, &cylinders, &heads, &secs);
585 p[2] = (cylinders >> 16) & 0xff;
586 p[3] = (cylinders >> 8) & 0xff;
587 p[4] = cylinders & 0xff;
588 p[5] = heads & 0xff;
589 /* Write precomp start cylinder, disabled */
590 p[6] = (cylinders >> 16) & 0xff;
591 p[7] = (cylinders >> 8) & 0xff;
592 p[8] = cylinders & 0xff;
593 /* Reduced current start cylinder, disabled */
594 p[9] = (cylinders >> 16) & 0xff;
595 p[10] = (cylinders >> 8) & 0xff;
596 p[11] = cylinders & 0xff;
597 /* Device step rate [ns], 200ns */
598 p[12] = 0;
599 p[13] = 200;
600 /* Landing zone cylinder */
601 p[14] = 0xff;
602 p[15] = 0xff;
603 p[16] = 0xff;
604 /* Medium rotation rate [rpm], 5400 rpm */
605 p[20] = (5400 >> 8) & 0xff;
606 p[21] = 5400 & 0xff;
607 return p[1] + 2;
609 case 5: /* Flexible disk device geometry page. */
610 p[0] = 5;
611 p[1] = 0x1e;
612 if (page_control == 1) { /* Changeable Values */
613 return p[1] + 2;
615 /* Transfer rate [kbit/s], 5Mbit/s */
616 p[2] = 5000 >> 8;
617 p[3] = 5000 & 0xff;
618 /* if a geometry hint is available, use it */
619 bdrv_get_geometry_hint(bdrv, &cylinders, &heads, &secs);
620 p[4] = heads & 0xff;
621 p[5] = secs & 0xff;
622 p[6] = s->cluster_size * 2;
623 p[8] = (cylinders >> 8) & 0xff;
624 p[9] = cylinders & 0xff;
625 /* Write precomp start cylinder, disabled */
626 p[10] = (cylinders >> 8) & 0xff;
627 p[11] = cylinders & 0xff;
628 /* Reduced current start cylinder, disabled */
629 p[12] = (cylinders >> 8) & 0xff;
630 p[13] = cylinders & 0xff;
631 /* Device step rate [100us], 100us */
632 p[14] = 0;
633 p[15] = 1;
634 /* Device step pulse width [us], 1us */
635 p[16] = 1;
636 /* Device head settle delay [100us], 100us */
637 p[17] = 0;
638 p[18] = 1;
639 /* Motor on delay [0.1s], 0.1s */
640 p[19] = 1;
641 /* Motor off delay [0.1s], 0.1s */
642 p[20] = 1;
643 /* Medium rotation rate [rpm], 5400 rpm */
644 p[28] = (5400 >> 8) & 0xff;
645 p[29] = 5400 & 0xff;
646 return p[1] + 2;
648 case 8: /* Caching page. */
649 p[0] = 8;
650 p[1] = 0x12;
651 if (page_control == 1) { /* Changeable Values */
652 return p[1] + 2;
654 if (bdrv_enable_write_cache(s->bs)) {
655 p[2] = 4; /* WCE */
657 return p[1] + 2;
659 case 0x2a: /* CD Capabilities and Mechanical Status page. */
660 if (s->qdev.type != TYPE_ROM)
661 return 0;
662 p[0] = 0x2a;
663 p[1] = 0x14;
664 if (page_control == 1) { /* Changeable Values */
665 return p[1] + 2;
667 p[2] = 3; // CD-R & CD-RW read
668 p[3] = 0; // Writing not supported
669 p[4] = 0x7f; /* Audio, composite, digital out,
670 mode 2 form 1&2, multi session */
671 p[5] = 0xff; /* CD DA, DA accurate, RW supported,
672 RW corrected, C2 errors, ISRC,
673 UPC, Bar code */
674 p[6] = 0x2d | (bdrv_is_locked(s->bs)? 2 : 0);
675 /* Locking supported, jumper present, eject, tray */
676 p[7] = 0; /* no volume & mute control, no
677 changer */
678 p[8] = (50 * 176) >> 8; // 50x read speed
679 p[9] = (50 * 176) & 0xff;
680 p[10] = 0 >> 8; // No volume
681 p[11] = 0 & 0xff;
682 p[12] = 2048 >> 8; // 2M buffer
683 p[13] = 2048 & 0xff;
684 p[14] = (16 * 176) >> 8; // 16x read speed current
685 p[15] = (16 * 176) & 0xff;
686 p[18] = (16 * 176) >> 8; // 16x write speed
687 p[19] = (16 * 176) & 0xff;
688 p[20] = (16 * 176) >> 8; // 16x write speed current
689 p[21] = (16 * 176) & 0xff;
690 return p[1] + 2;
692 default:
693 return 0;
697 static int scsi_disk_emulate_mode_sense(SCSIRequest *req, uint8_t *outbuf)
699 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev);
700 uint64_t nb_sectors;
701 int page, dbd, buflen, page_control;
702 uint8_t *p;
703 uint8_t dev_specific_param;
705 dbd = req->cmd.buf[1] & 0x8;
706 page = req->cmd.buf[2] & 0x3f;
707 page_control = (req->cmd.buf[2] & 0xc0) >> 6;
708 DPRINTF("Mode Sense(%d) (page %d, xfer %zd, page_control %d)\n",
709 (req->cmd.buf[0] == MODE_SENSE) ? 6 : 10, page, req->cmd.xfer, page_control);
710 memset(outbuf, 0, req->cmd.xfer);
711 p = outbuf;
713 if (bdrv_is_read_only(s->bs)) {
714 dev_specific_param = 0x80; /* Readonly. */
715 } else {
716 dev_specific_param = 0x00;
719 if (req->cmd.buf[0] == MODE_SENSE) {
720 p[1] = 0; /* Default media type. */
721 p[2] = dev_specific_param;
722 p[3] = 0; /* Block descriptor length. */
723 p += 4;
724 } else { /* MODE_SENSE_10 */
725 p[2] = 0; /* Default media type. */
726 p[3] = dev_specific_param;
727 p[6] = p[7] = 0; /* Block descriptor length. */
728 p += 8;
731 bdrv_get_geometry(s->bs, &nb_sectors);
732 if (!dbd && nb_sectors) {
733 if (req->cmd.buf[0] == MODE_SENSE) {
734 outbuf[3] = 8; /* Block descriptor length */
735 } else { /* MODE_SENSE_10 */
736 outbuf[7] = 8; /* Block descriptor length */
738 nb_sectors /= s->cluster_size;
739 if (nb_sectors > 0xffffff)
740 nb_sectors = 0;
741 p[0] = 0; /* media density code */
742 p[1] = (nb_sectors >> 16) & 0xff;
743 p[2] = (nb_sectors >> 8) & 0xff;
744 p[3] = nb_sectors & 0xff;
745 p[4] = 0; /* reserved */
746 p[5] = 0; /* bytes 5-7 are the sector size in bytes */
747 p[6] = s->cluster_size * 2;
748 p[7] = 0;
749 p += 8;
752 if (page_control == 3) { /* Saved Values */
753 return -1; /* ILLEGAL_REQUEST */
756 switch (page) {
757 case 0x04:
758 case 0x05:
759 case 0x08:
760 case 0x2a:
761 p += mode_sense_page(req, page, p, page_control);
762 break;
763 case 0x3f:
764 p += mode_sense_page(req, 0x08, p, page_control);
765 p += mode_sense_page(req, 0x2a, p, page_control);
766 break;
767 default:
768 return -1; /* ILLEGAL_REQUEST */
771 buflen = p - outbuf;
773 * The mode data length field specifies the length in bytes of the
774 * following data that is available to be transferred. The mode data
775 * length does not include itself.
777 if (req->cmd.buf[0] == MODE_SENSE) {
778 outbuf[0] = buflen - 1;
779 } else { /* MODE_SENSE_10 */
780 outbuf[0] = ((buflen - 2) >> 8) & 0xff;
781 outbuf[1] = (buflen - 2) & 0xff;
783 if (buflen > req->cmd.xfer)
784 buflen = req->cmd.xfer;
785 return buflen;
788 static int scsi_disk_emulate_read_toc(SCSIRequest *req, uint8_t *outbuf)
790 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev);
791 int start_track, format, msf, toclen;
792 uint64_t nb_sectors;
794 msf = req->cmd.buf[1] & 2;
795 format = req->cmd.buf[2] & 0xf;
796 start_track = req->cmd.buf[6];
797 bdrv_get_geometry(s->bs, &nb_sectors);
798 DPRINTF("Read TOC (track %d format %d msf %d)\n", start_track, format, msf >> 1);
799 nb_sectors /= s->cluster_size;
800 switch (format) {
801 case 0:
802 toclen = cdrom_read_toc(nb_sectors, outbuf, msf, start_track);
803 break;
804 case 1:
805 /* multi session : only a single session defined */
806 toclen = 12;
807 memset(outbuf, 0, 12);
808 outbuf[1] = 0x0a;
809 outbuf[2] = 0x01;
810 outbuf[3] = 0x01;
811 break;
812 case 2:
813 toclen = cdrom_read_toc_raw(nb_sectors, outbuf, msf, start_track);
814 break;
815 default:
816 return -1;
818 if (toclen > req->cmd.xfer)
819 toclen = req->cmd.xfer;
820 return toclen;
823 static int scsi_disk_emulate_command(SCSIDiskReq *r, uint8_t *outbuf)
825 SCSIRequest *req = &r->req;
826 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev);
827 uint64_t nb_sectors;
828 int buflen = 0;
829 int ret;
831 switch (req->cmd.buf[0]) {
832 case TEST_UNIT_READY:
833 if (!bdrv_is_inserted(s->bs))
834 goto not_ready;
835 break;
836 case REQUEST_SENSE:
837 if (req->cmd.xfer < 4)
838 goto illegal_request;
839 buflen = scsi_build_sense(s->sense, outbuf, req->cmd.xfer,
840 req->cmd.xfer > 13);
841 scsi_disk_clear_sense(s);
842 break;
843 case INQUIRY:
844 buflen = scsi_disk_emulate_inquiry(req, outbuf);
845 if (buflen < 0)
846 goto illegal_request;
847 break;
848 case MODE_SENSE:
849 case MODE_SENSE_10:
850 buflen = scsi_disk_emulate_mode_sense(req, outbuf);
851 if (buflen < 0)
852 goto illegal_request;
853 break;
854 case READ_TOC:
855 buflen = scsi_disk_emulate_read_toc(req, outbuf);
856 if (buflen < 0)
857 goto illegal_request;
858 break;
859 case RESERVE:
860 if (req->cmd.buf[1] & 1)
861 goto illegal_request;
862 break;
863 case RESERVE_10:
864 if (req->cmd.buf[1] & 3)
865 goto illegal_request;
866 break;
867 case RELEASE:
868 if (req->cmd.buf[1] & 1)
869 goto illegal_request;
870 break;
871 case RELEASE_10:
872 if (req->cmd.buf[1] & 3)
873 goto illegal_request;
874 break;
875 case START_STOP:
876 if (s->qdev.type == TYPE_ROM && (req->cmd.buf[4] & 2)) {
877 /* load/eject medium */
878 bdrv_eject(s->bs, !(req->cmd.buf[4] & 1));
880 break;
881 case ALLOW_MEDIUM_REMOVAL:
882 bdrv_set_locked(s->bs, req->cmd.buf[4] & 1);
883 break;
884 case READ_CAPACITY_10:
885 /* The normal LEN field for this command is zero. */
886 memset(outbuf, 0, 8);
887 bdrv_get_geometry(s->bs, &nb_sectors);
888 if (!nb_sectors)
889 goto not_ready;
890 nb_sectors /= s->cluster_size;
891 /* Returned value is the address of the last sector. */
892 nb_sectors--;
893 /* Remember the new size for read/write sanity checking. */
894 s->max_lba = nb_sectors;
895 /* Clip to 2TB, instead of returning capacity modulo 2TB. */
896 if (nb_sectors > UINT32_MAX)
897 nb_sectors = UINT32_MAX;
898 outbuf[0] = (nb_sectors >> 24) & 0xff;
899 outbuf[1] = (nb_sectors >> 16) & 0xff;
900 outbuf[2] = (nb_sectors >> 8) & 0xff;
901 outbuf[3] = nb_sectors & 0xff;
902 outbuf[4] = 0;
903 outbuf[5] = 0;
904 outbuf[6] = s->cluster_size * 2;
905 outbuf[7] = 0;
906 buflen = 8;
907 break;
908 case SYNCHRONIZE_CACHE:
909 ret = bdrv_flush(s->bs);
910 if (ret < 0) {
911 if (scsi_handle_rw_error(r, -ret, SCSI_REQ_STATUS_RETRY_FLUSH)) {
912 return -1;
915 break;
916 case GET_CONFIGURATION:
917 memset(outbuf, 0, 8);
918 /* ??? This should probably return much more information. For now
919 just return the basic header indicating the CD-ROM profile. */
920 outbuf[7] = 8; // CD-ROM
921 buflen = 8;
922 break;
923 case SERVICE_ACTION_IN:
924 /* Service Action In subcommands. */
925 if ((req->cmd.buf[1] & 31) == 0x10) {
926 DPRINTF("SAI READ CAPACITY(16)\n");
927 memset(outbuf, 0, req->cmd.xfer);
928 bdrv_get_geometry(s->bs, &nb_sectors);
929 if (!nb_sectors)
930 goto not_ready;
931 nb_sectors /= s->cluster_size;
932 /* Returned value is the address of the last sector. */
933 nb_sectors--;
934 /* Remember the new size for read/write sanity checking. */
935 s->max_lba = nb_sectors;
936 outbuf[0] = (nb_sectors >> 56) & 0xff;
937 outbuf[1] = (nb_sectors >> 48) & 0xff;
938 outbuf[2] = (nb_sectors >> 40) & 0xff;
939 outbuf[3] = (nb_sectors >> 32) & 0xff;
940 outbuf[4] = (nb_sectors >> 24) & 0xff;
941 outbuf[5] = (nb_sectors >> 16) & 0xff;
942 outbuf[6] = (nb_sectors >> 8) & 0xff;
943 outbuf[7] = nb_sectors & 0xff;
944 outbuf[8] = 0;
945 outbuf[9] = 0;
946 outbuf[10] = s->cluster_size * 2;
947 outbuf[11] = 0;
948 outbuf[12] = 0;
949 outbuf[13] = get_physical_block_exp(&s->qdev.conf);
951 /* set TPE bit if the format supports discard */
952 if (s->qdev.conf.discard_granularity) {
953 outbuf[14] = 0x80;
956 /* Protection, exponent and lowest lba field left blank. */
957 buflen = req->cmd.xfer;
958 break;
960 DPRINTF("Unsupported Service Action In\n");
961 goto illegal_request;
962 case REPORT_LUNS:
963 if (req->cmd.xfer < 16)
964 goto illegal_request;
965 memset(outbuf, 0, 16);
966 outbuf[3] = 8;
967 buflen = 16;
968 break;
969 case VERIFY_10:
970 break;
971 default:
972 scsi_command_complete(r, CHECK_CONDITION, SENSE_CODE(INVALID_OPCODE));
973 return -1;
975 scsi_req_set_status(r, GOOD, SENSE_CODE(NO_SENSE));
976 return buflen;
978 not_ready:
979 if (!bdrv_is_inserted(s->bs)) {
980 scsi_command_complete(r, CHECK_CONDITION, SENSE_CODE(NO_MEDIUM));
981 } else {
982 scsi_command_complete(r, CHECK_CONDITION, SENSE_CODE(LUN_NOT_READY));
984 return -1;
986 illegal_request:
987 scsi_command_complete(r, CHECK_CONDITION, SENSE_CODE(INVALID_FIELD));
988 return -1;
991 /* Execute a scsi command. Returns the length of the data expected by the
992 command. This will be Positive for data transfers from the device
993 (eg. disk reads), negative for transfers to the device (eg. disk writes),
994 and zero if the command does not transfer any data. */
996 static int32_t scsi_send_command(SCSIRequest *req, uint8_t *buf)
998 SCSIDiskReq *r = DO_UPCAST(SCSIDiskReq, req, req);
999 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev);
1000 int32_t len;
1001 uint8_t command;
1002 uint8_t *outbuf;
1003 int rc;
1005 command = buf[0];
1006 outbuf = (uint8_t *)r->iov.iov_base;
1007 DPRINTF("Command: lun=%d tag=0x%x data=0x%02x", req->lun, req->tag, buf[0]);
1009 if (scsi_req_parse(&r->req, buf) != 0) {
1010 BADF("Unsupported command length, command %x\n", command);
1011 scsi_command_complete(r, CHECK_CONDITION, SENSE_CODE(INVALID_OPCODE));
1012 return 0;
1014 #ifdef DEBUG_SCSI
1016 int i;
1017 for (i = 1; i < r->req.cmd.len; i++) {
1018 printf(" 0x%02x", buf[i]);
1020 printf("\n");
1022 #endif
1024 if (req->lun) {
1025 /* Only LUN 0 supported. */
1026 DPRINTF("Unimplemented LUN %d\n", req->lun);
1027 if (command != REQUEST_SENSE && command != INQUIRY) {
1028 scsi_command_complete(r, CHECK_CONDITION,
1029 SENSE_CODE(LUN_NOT_SUPPORTED));
1030 return 0;
1033 switch (command) {
1034 case TEST_UNIT_READY:
1035 case REQUEST_SENSE:
1036 case INQUIRY:
1037 case MODE_SENSE:
1038 case MODE_SENSE_10:
1039 case RESERVE:
1040 case RESERVE_10:
1041 case RELEASE:
1042 case RELEASE_10:
1043 case START_STOP:
1044 case ALLOW_MEDIUM_REMOVAL:
1045 case READ_CAPACITY_10:
1046 case SYNCHRONIZE_CACHE:
1047 case READ_TOC:
1048 case GET_CONFIGURATION:
1049 case SERVICE_ACTION_IN:
1050 case REPORT_LUNS:
1051 case VERIFY_10:
1052 rc = scsi_disk_emulate_command(r, outbuf);
1053 if (rc < 0) {
1054 return 0;
1057 r->iov.iov_len = rc;
1058 break;
1059 case READ_6:
1060 case READ_10:
1061 case READ_12:
1062 case READ_16:
1063 len = r->req.cmd.xfer / s->qdev.blocksize;
1064 DPRINTF("Read (sector %" PRId64 ", count %d)\n", r->req.cmd.lba, len);
1065 if (r->req.cmd.lba > s->max_lba)
1066 goto illegal_lba;
1067 r->sector = r->req.cmd.lba * s->cluster_size;
1068 r->sector_count = len * s->cluster_size;
1069 break;
1070 case WRITE_6:
1071 case WRITE_10:
1072 case WRITE_12:
1073 case WRITE_16:
1074 case WRITE_VERIFY_10:
1075 case WRITE_VERIFY_12:
1076 case WRITE_VERIFY_16:
1077 len = r->req.cmd.xfer / s->qdev.blocksize;
1078 DPRINTF("Write %s(sector %" PRId64 ", count %d)\n",
1079 (command & 0xe) == 0xe ? "And Verify " : "",
1080 r->req.cmd.lba, len);
1081 if (r->req.cmd.lba > s->max_lba)
1082 goto illegal_lba;
1083 r->sector = r->req.cmd.lba * s->cluster_size;
1084 r->sector_count = len * s->cluster_size;
1085 break;
1086 case MODE_SELECT:
1087 DPRINTF("Mode Select(6) (len %lu)\n", (long)r->req.cmd.xfer);
1088 /* We don't support mode parameter changes.
1089 Allow the mode parameter header + block descriptors only. */
1090 if (r->req.cmd.xfer > 12) {
1091 goto fail;
1093 break;
1094 case MODE_SELECT_10:
1095 DPRINTF("Mode Select(10) (len %lu)\n", (long)r->req.cmd.xfer);
1096 /* We don't support mode parameter changes.
1097 Allow the mode parameter header + block descriptors only. */
1098 if (r->req.cmd.xfer > 16) {
1099 goto fail;
1101 break;
1102 case SEEK_6:
1103 case SEEK_10:
1104 DPRINTF("Seek(%d) (sector %" PRId64 ")\n", command == SEEK_6 ? 6 : 10,
1105 r->req.cmd.lba);
1106 if (r->req.cmd.lba > s->max_lba) {
1107 goto illegal_lba;
1109 break;
1110 case WRITE_SAME_16:
1111 len = r->req.cmd.xfer / s->qdev.blocksize;
1113 DPRINTF("WRITE SAME(16) (sector %" PRId64 ", count %d)\n",
1114 r->req.cmd.lba, len);
1116 if (r->req.cmd.lba > s->max_lba) {
1117 goto illegal_lba;
1121 * We only support WRITE SAME with the unmap bit set for now.
1123 if (!(buf[1] & 0x8)) {
1124 goto fail;
1127 rc = bdrv_discard(s->bs, r->req.cmd.lba * s->cluster_size,
1128 len * s->cluster_size);
1129 if (rc < 0) {
1130 /* XXX: better error code ?*/
1131 goto fail;
1134 break;
1135 default:
1136 DPRINTF("Unknown SCSI command (%2.2x)\n", buf[0]);
1137 scsi_command_complete(r, CHECK_CONDITION, SENSE_CODE(INVALID_OPCODE));
1138 return 0;
1139 fail:
1140 scsi_command_complete(r, CHECK_CONDITION, SENSE_CODE(INVALID_FIELD));
1141 return 0;
1142 illegal_lba:
1143 scsi_command_complete(r, CHECK_CONDITION, SENSE_CODE(LBA_OUT_OF_RANGE));
1144 return 0;
1146 if (r->sector_count == 0 && r->iov.iov_len == 0) {
1147 scsi_command_complete(r, GOOD, SENSE_CODE(NO_SENSE));
1149 len = r->sector_count * 512 + r->iov.iov_len;
1150 if (r->req.cmd.mode == SCSI_XFER_TO_DEV) {
1151 return -len;
1152 } else {
1153 if (!r->sector_count)
1154 r->sector_count = -1;
1155 return len;
1159 static void scsi_disk_reset(DeviceState *dev)
1161 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev.qdev, dev);
1162 uint64_t nb_sectors;
1164 scsi_device_purge_requests(&s->qdev);
1166 bdrv_get_geometry(s->bs, &nb_sectors);
1167 nb_sectors /= s->cluster_size;
1168 if (nb_sectors) {
1169 nb_sectors--;
1171 s->max_lba = nb_sectors;
1174 static void scsi_destroy(SCSIDevice *dev)
1176 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
1178 scsi_device_purge_requests(&s->qdev);
1179 blockdev_mark_auto_del(s->qdev.conf.bs);
1182 static int scsi_initfn(SCSIDevice *dev, uint8_t scsi_type)
1184 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
1185 DriveInfo *dinfo;
1187 if (!s->qdev.conf.bs) {
1188 error_report("scsi-disk: drive property not set");
1189 return -1;
1191 s->bs = s->qdev.conf.bs;
1193 if (scsi_type == TYPE_DISK && !bdrv_is_inserted(s->bs)) {
1194 error_report("Device needs media, but drive is empty");
1195 return -1;
1198 if (!s->serial) {
1199 /* try to fall back to value set with legacy -drive serial=... */
1200 dinfo = drive_get_by_blockdev(s->bs);
1201 if (*dinfo->serial) {
1202 s->serial = qemu_strdup(dinfo->serial);
1206 if (!s->version) {
1207 s->version = qemu_strdup(QEMU_VERSION);
1210 if (bdrv_is_sg(s->bs)) {
1211 error_report("scsi-disk: unwanted /dev/sg*");
1212 return -1;
1215 if (scsi_type == TYPE_ROM) {
1216 s->qdev.blocksize = 2048;
1217 } else if (scsi_type == TYPE_DISK) {
1218 s->qdev.blocksize = s->qdev.conf.logical_block_size;
1219 } else {
1220 error_report("scsi-disk: Unhandled SCSI type %02x", scsi_type);
1221 return -1;
1223 s->cluster_size = s->qdev.blocksize / 512;
1224 s->bs->buffer_alignment = s->qdev.blocksize;
1226 s->qdev.type = scsi_type;
1227 qemu_add_vm_change_state_handler(scsi_dma_restart_cb, s);
1228 bdrv_set_removable(s->bs, scsi_type == TYPE_ROM);
1229 add_boot_device_path(s->qdev.conf.bootindex, &dev->qdev, ",0");
1230 return 0;
1233 static int scsi_hd_initfn(SCSIDevice *dev)
1235 return scsi_initfn(dev, TYPE_DISK);
1238 static int scsi_cd_initfn(SCSIDevice *dev)
1240 return scsi_initfn(dev, TYPE_ROM);
1243 static int scsi_disk_initfn(SCSIDevice *dev)
1245 DriveInfo *dinfo;
1246 uint8_t scsi_type;
1248 if (!dev->conf.bs) {
1249 scsi_type = TYPE_DISK; /* will die in scsi_initfn() */
1250 } else {
1251 dinfo = drive_get_by_blockdev(dev->conf.bs);
1252 scsi_type = dinfo->media_cd ? TYPE_ROM : TYPE_DISK;
1255 return scsi_initfn(dev, scsi_type);
1258 #define DEFINE_SCSI_DISK_PROPERTIES() \
1259 DEFINE_BLOCK_PROPERTIES(SCSIDiskState, qdev.conf), \
1260 DEFINE_PROP_STRING("ver", SCSIDiskState, version), \
1261 DEFINE_PROP_STRING("serial", SCSIDiskState, serial)
1263 static SCSIDeviceInfo scsi_disk_info[] = {
1265 .qdev.name = "scsi-hd",
1266 .qdev.fw_name = "disk",
1267 .qdev.desc = "virtual SCSI disk",
1268 .qdev.size = sizeof(SCSIDiskState),
1269 .qdev.reset = scsi_disk_reset,
1270 .init = scsi_hd_initfn,
1271 .destroy = scsi_destroy,
1272 .alloc_req = scsi_new_request,
1273 .free_req = scsi_free_request,
1274 .send_command = scsi_send_command,
1275 .read_data = scsi_read_data,
1276 .write_data = scsi_write_data,
1277 .cancel_io = scsi_cancel_io,
1278 .get_buf = scsi_get_buf,
1279 .get_sense = scsi_get_sense,
1280 .qdev.props = (Property[]) {
1281 DEFINE_SCSI_DISK_PROPERTIES(),
1282 DEFINE_PROP_BIT("removable", SCSIDiskState, removable, 0, false),
1283 DEFINE_PROP_END_OF_LIST(),
1286 .qdev.name = "scsi-cd",
1287 .qdev.fw_name = "disk",
1288 .qdev.desc = "virtual SCSI CD-ROM",
1289 .qdev.size = sizeof(SCSIDiskState),
1290 .qdev.reset = scsi_disk_reset,
1291 .init = scsi_cd_initfn,
1292 .destroy = scsi_destroy,
1293 .alloc_req = scsi_new_request,
1294 .free_req = scsi_free_request,
1295 .send_command = scsi_send_command,
1296 .read_data = scsi_read_data,
1297 .write_data = scsi_write_data,
1298 .cancel_io = scsi_cancel_io,
1299 .get_buf = scsi_get_buf,
1300 .get_sense = scsi_get_sense,
1301 .qdev.props = (Property[]) {
1302 DEFINE_SCSI_DISK_PROPERTIES(),
1303 DEFINE_PROP_END_OF_LIST(),
1306 .qdev.name = "scsi-disk", /* legacy -device scsi-disk */
1307 .qdev.fw_name = "disk",
1308 .qdev.desc = "virtual SCSI disk or CD-ROM (legacy)",
1309 .qdev.size = sizeof(SCSIDiskState),
1310 .qdev.reset = scsi_disk_reset,
1311 .init = scsi_disk_initfn,
1312 .destroy = scsi_destroy,
1313 .alloc_req = scsi_new_request,
1314 .free_req = scsi_free_request,
1315 .send_command = scsi_send_command,
1316 .read_data = scsi_read_data,
1317 .write_data = scsi_write_data,
1318 .cancel_io = scsi_cancel_io,
1319 .get_buf = scsi_get_buf,
1320 .get_sense = scsi_get_sense,
1321 .qdev.props = (Property[]) {
1322 DEFINE_SCSI_DISK_PROPERTIES(),
1323 DEFINE_PROP_BIT("removable", SCSIDiskState, removable, 0, false),
1324 DEFINE_PROP_END_OF_LIST(),
1329 static void scsi_disk_register_devices(void)
1331 int i;
1333 for (i = 0; i < ARRAY_SIZE(scsi_disk_info); i++) {
1334 scsi_qdev_register(&scsi_disk_info[i]);
1337 device_init(scsi_disk_register_devices)