1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24#ifdef DEBUG_SCSI
25#define DPRINTF(fmt, ...) \
26do { printf("scsi-disk: " fmt , ## __VA_ARGS__); } while (0)
27#else
28#define DPRINTF(fmt, ...) do {} while(0)
29#endif
30
31#include "qemu/osdep.h"
32#include "qapi/error.h"
33#include "qemu/error-report.h"
34#include "hw/scsi/scsi.h"
35#include "block/scsi.h"
36#include "sysemu/sysemu.h"
37#include "sysemu/block-backend.h"
38#include "sysemu/blockdev.h"
39#include "hw/block/block.h"
40#include "sysemu/dma.h"
41#include "qemu/cutils.h"
42
43#ifdef __linux
44#include <scsi/sg.h>
45#endif
46
47#define SCSI_WRITE_SAME_MAX 524288
48#define SCSI_DMA_BUF_SIZE 131072
49#define SCSI_MAX_INQUIRY_LEN 256
50#define SCSI_MAX_MODE_LEN 256
51
52#define DEFAULT_DISCARD_GRANULARITY 4096
53#define DEFAULT_MAX_UNMAP_SIZE (1 << 30)
54#define DEFAULT_MAX_IO_SIZE INT_MAX
55
56typedef struct SCSIDiskState SCSIDiskState;
57
58typedef struct SCSIDiskReq {
59 SCSIRequest req;
60
61 uint64_t sector;
62 uint32_t sector_count;
63 uint32_t buflen;
64 bool started;
65 struct iovec iov;
66 QEMUIOVector qiov;
67 BlockAcctCookie acct;
68} SCSIDiskReq;
69
70#define SCSI_DISK_F_REMOVABLE 0
71#define SCSI_DISK_F_DPOFUA 1
72#define SCSI_DISK_F_NO_REMOVABLE_DEVOPS 2
73
74struct SCSIDiskState
75{
76 SCSIDevice qdev;
77 uint32_t features;
78 bool media_changed;
79 bool media_event;
80 bool eject_request;
81 uint16_t port_index;
82 uint64_t max_unmap_size;
83 uint64_t max_io_size;
84 QEMUBH *bh;
85 char *version;
86 char *serial;
87 char *vendor;
88 char *product;
89 bool tray_open;
90 bool tray_locked;
91};
92
93static int scsi_handle_rw_error(SCSIDiskReq *r, int error, bool acct_failed);
94
95static void scsi_free_request(SCSIRequest *req)
96{
97 SCSIDiskReq *r = DO_UPCAST(SCSIDiskReq, req, req);
98
99 qemu_vfree(r->iov.iov_base);
100}
101
102
103static void scsi_check_condition(SCSIDiskReq *r, SCSISense sense)
104{
105 DPRINTF("Command complete tag=0x%x sense=%d/%d/%d\n",
106 r->req.tag, sense.key, sense.asc, sense.ascq);
107 scsi_req_build_sense(&r->req, sense);
108 scsi_req_complete(&r->req, CHECK_CONDITION);
109}
110
111static uint32_t scsi_init_iovec(SCSIDiskReq *r, size_t size)
112{
113 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
114
115 if (!r->iov.iov_base) {
116 r->buflen = size;
117 r->iov.iov_base = blk_blockalign(s->qdev.conf.blk, r->buflen);
118 }
119 r->iov.iov_len = MIN(r->sector_count * 512, r->buflen);
120 qemu_iovec_init_external(&r->qiov, &r->iov, 1);
121 return r->qiov.size / 512;
122}
123
124static void scsi_disk_save_request(QEMUFile *f, SCSIRequest *req)
125{
126 SCSIDiskReq *r = DO_UPCAST(SCSIDiskReq, req, req);
127
128 qemu_put_be64s(f, &r->sector);
129 qemu_put_be32s(f, &r->sector_count);
130 qemu_put_be32s(f, &r->buflen);
131 if (r->buflen) {
132 if (r->req.cmd.mode == SCSI_XFER_TO_DEV) {
133 qemu_put_buffer(f, r->iov.iov_base, r->iov.iov_len);
134 } else if (!req->retry) {
135 uint32_t len = r->iov.iov_len;
136 qemu_put_be32s(f, &len);
137 qemu_put_buffer(f, r->iov.iov_base, r->iov.iov_len);
138 }
139 }
140}
141
142static void scsi_disk_load_request(QEMUFile *f, SCSIRequest *req)
143{
144 SCSIDiskReq *r = DO_UPCAST(SCSIDiskReq, req, req);
145
146 qemu_get_be64s(f, &r->sector);
147 qemu_get_be32s(f, &r->sector_count);
148 qemu_get_be32s(f, &r->buflen);
149 if (r->buflen) {
150 scsi_init_iovec(r, r->buflen);
151 if (r->req.cmd.mode == SCSI_XFER_TO_DEV) {
152 qemu_get_buffer(f, r->iov.iov_base, r->iov.iov_len);
153 } else if (!r->req.retry) {
154 uint32_t len;
155 qemu_get_be32s(f, &len);
156 r->iov.iov_len = len;
157 assert(r->iov.iov_len <= r->buflen);
158 qemu_get_buffer(f, r->iov.iov_base, r->iov.iov_len);
159 }
160 }
161
162 qemu_iovec_init_external(&r->qiov, &r->iov, 1);
163}
164
165static void scsi_aio_complete(void *opaque, int ret)
166{
167 SCSIDiskReq *r = (SCSIDiskReq *)opaque;
168 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
169
170 assert(r->req.aiocb != NULL);
171 r->req.aiocb = NULL;
172 if (r->req.io_canceled) {
173 scsi_req_cancel_complete(&r->req);
174 goto done;
175 }
176
177 if (ret < 0) {
178 if (scsi_handle_rw_error(r, -ret, true)) {
179 goto done;
180 }
181 }
182
183 block_acct_done(blk_get_stats(s->qdev.conf.blk), &r->acct);
184 scsi_req_complete(&r->req, GOOD);
185
186done:
187 scsi_req_unref(&r->req);
188}
189
190static bool scsi_is_cmd_fua(SCSICommand *cmd)
191{
192 switch (cmd->buf[0]) {
193 case READ_10:
194 case READ_12:
195 case READ_16:
196 case WRITE_10:
197 case WRITE_12:
198 case WRITE_16:
199 return (cmd->buf[1] & 8) != 0;
200
201 case VERIFY_10:
202 case VERIFY_12:
203 case VERIFY_16:
204 case WRITE_VERIFY_10:
205 case WRITE_VERIFY_12:
206 case WRITE_VERIFY_16:
207 return true;
208
209 case READ_6:
210 case WRITE_6:
211 default:
212 return false;
213 }
214}
215
216static void scsi_write_do_fua(SCSIDiskReq *r)
217{
218 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
219
220 assert(r->req.aiocb == NULL);
221
222 if (r->req.io_canceled) {
223 scsi_req_cancel_complete(&r->req);
224 goto done;
225 }
226
227 if (scsi_is_cmd_fua(&r->req.cmd)) {
228 block_acct_start(blk_get_stats(s->qdev.conf.blk), &r->acct, 0,
229 BLOCK_ACCT_FLUSH);
230 r->req.aiocb = blk_aio_flush(s->qdev.conf.blk, scsi_aio_complete, r);
231 return;
232 }
233
234 scsi_req_complete(&r->req, GOOD);
235
236done:
237 scsi_req_unref(&r->req);
238}
239
240static void scsi_dma_complete_noio(SCSIDiskReq *r, int ret)
241{
242 assert(r->req.aiocb == NULL);
243
244 if (r->req.io_canceled) {
245 scsi_req_cancel_complete(&r->req);
246 goto done;
247 }
248
249 if (ret < 0) {
250 if (scsi_handle_rw_error(r, -ret, false)) {
251 goto done;
252 }
253 }
254
255 r->sector += r->sector_count;
256 r->sector_count = 0;
257 if (r->req.cmd.mode == SCSI_XFER_TO_DEV) {
258 scsi_write_do_fua(r);
259 return;
260 } else {
261 scsi_req_complete(&r->req, GOOD);
262 }
263
264done:
265 scsi_req_unref(&r->req);
266}
267
268static void scsi_dma_complete(void *opaque, int ret)
269{
270 SCSIDiskReq *r = (SCSIDiskReq *)opaque;
271 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
272
273 assert(r->req.aiocb != NULL);
274 r->req.aiocb = NULL;
275
276 if (ret < 0) {
277 block_acct_failed(blk_get_stats(s->qdev.conf.blk), &r->acct);
278 } else {
279 block_acct_done(blk_get_stats(s->qdev.conf.blk), &r->acct);
280 }
281 scsi_dma_complete_noio(r, ret);
282}
283
284static void scsi_read_complete(void * opaque, int ret)
285{
286 SCSIDiskReq *r = (SCSIDiskReq *)opaque;
287 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
288 int n;
289
290 assert(r->req.aiocb != NULL);
291 r->req.aiocb = NULL;
292 if (r->req.io_canceled) {
293 scsi_req_cancel_complete(&r->req);
294 goto done;
295 }
296
297 if (ret < 0) {
298 if (scsi_handle_rw_error(r, -ret, true)) {
299 goto done;
300 }
301 }
302
303 block_acct_done(blk_get_stats(s->qdev.conf.blk), &r->acct);
304 DPRINTF("Data ready tag=0x%x len=%zd\n", r->req.tag, r->qiov.size);
305
306 n = r->qiov.size / 512;
307 r->sector += n;
308 r->sector_count -= n;
309 scsi_req_data(&r->req, r->qiov.size);
310
311done:
312 scsi_req_unref(&r->req);
313}
314
315
316static void scsi_do_read(SCSIDiskReq *r, int ret)
317{
318 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
319 uint32_t n;
320
321 assert (r->req.aiocb == NULL);
322
323 if (r->req.io_canceled) {
324 scsi_req_cancel_complete(&r->req);
325 goto done;
326 }
327
328 if (ret < 0) {
329 if (scsi_handle_rw_error(r, -ret, false)) {
330 goto done;
331 }
332 }
333
334
335 scsi_req_ref(&r->req);
336
337 if (r->req.sg) {
338 dma_acct_start(s->qdev.conf.blk, &r->acct, r->req.sg, BLOCK_ACCT_READ);
339 r->req.resid -= r->req.sg->size;
340 r->req.aiocb = dma_blk_read(s->qdev.conf.blk, r->req.sg, r->sector,
341 scsi_dma_complete, r);
342 } else {
343 n = scsi_init_iovec(r, SCSI_DMA_BUF_SIZE);
344 block_acct_start(blk_get_stats(s->qdev.conf.blk), &r->acct,
345 n * BDRV_SECTOR_SIZE, BLOCK_ACCT_READ);
346 r->req.aiocb = blk_aio_readv(s->qdev.conf.blk, r->sector, &r->qiov, n,
347 scsi_read_complete, r);
348 }
349
350done:
351 scsi_req_unref(&r->req);
352}
353
354static void scsi_do_read_cb(void *opaque, int ret)
355{
356 SCSIDiskReq *r = (SCSIDiskReq *)opaque;
357 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
358
359 assert (r->req.aiocb != NULL);
360 r->req.aiocb = NULL;
361
362 if (ret < 0) {
363 block_acct_failed(blk_get_stats(s->qdev.conf.blk), &r->acct);
364 } else {
365 block_acct_done(blk_get_stats(s->qdev.conf.blk), &r->acct);
366 }
367 scsi_do_read(opaque, ret);
368}
369
370
371static void scsi_read_data(SCSIRequest *req)
372{
373 SCSIDiskReq *r = DO_UPCAST(SCSIDiskReq, req, req);
374 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
375 bool first;
376
377 DPRINTF("Read sector_count=%d\n", r->sector_count);
378 if (r->sector_count == 0) {
379
380 scsi_req_complete(&r->req, GOOD);
381 return;
382 }
383
384
385 assert(r->req.aiocb == NULL);
386
387
388 scsi_req_ref(&r->req);
389 if (r->req.cmd.mode == SCSI_XFER_TO_DEV) {
390 DPRINTF("Data transfer direction invalid\n");
391 scsi_read_complete(r, -EINVAL);
392 return;
393 }
394
395 if (s->tray_open) {
396 scsi_read_complete(r, -ENOMEDIUM);
397 return;
398 }
399
400 first = !r->started;
401 r->started = true;
402 if (first && scsi_is_cmd_fua(&r->req.cmd)) {
403 block_acct_start(blk_get_stats(s->qdev.conf.blk), &r->acct, 0,
404 BLOCK_ACCT_FLUSH);
405 r->req.aiocb = blk_aio_flush(s->qdev.conf.blk, scsi_do_read_cb, r);
406 } else {
407 scsi_do_read(r, 0);
408 }
409}
410
411
412
413
414
415
416
417
418static int scsi_handle_rw_error(SCSIDiskReq *r, int error, bool acct_failed)
419{
420 bool is_read = (r->req.cmd.mode == SCSI_XFER_FROM_DEV);
421 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
422 BlockErrorAction action = blk_get_error_action(s->qdev.conf.blk,
423 is_read, error);
424
425 if (action == BLOCK_ERROR_ACTION_REPORT) {
426 if (acct_failed) {
427 block_acct_failed(blk_get_stats(s->qdev.conf.blk), &r->acct);
428 }
429 switch (error) {
430 case ENOMEDIUM:
431 scsi_check_condition(r, SENSE_CODE(NO_MEDIUM));
432 break;
433 case ENOMEM:
434 scsi_check_condition(r, SENSE_CODE(TARGET_FAILURE));
435 break;
436 case EINVAL:
437 scsi_check_condition(r, SENSE_CODE(INVALID_FIELD));
438 break;
439 case ENOSPC:
440 scsi_check_condition(r, SENSE_CODE(SPACE_ALLOC_FAILED));
441 break;
442 default:
443 scsi_check_condition(r, SENSE_CODE(IO_ERROR));
444 break;
445 }
446 }
447 blk_error_action(s->qdev.conf.blk, action, is_read, error);
448 if (action == BLOCK_ERROR_ACTION_STOP) {
449 scsi_req_retry(&r->req);
450 }
451 return action != BLOCK_ERROR_ACTION_IGNORE;
452}
453
454static void scsi_write_complete_noio(SCSIDiskReq *r, int ret)
455{
456 uint32_t n;
457
458 assert (r->req.aiocb == NULL);
459
460 if (r->req.io_canceled) {
461 scsi_req_cancel_complete(&r->req);
462 goto done;
463 }
464
465 if (ret < 0) {
466 if (scsi_handle_rw_error(r, -ret, false)) {
467 goto done;
468 }
469 }
470
471 n = r->qiov.size / 512;
472 r->sector += n;
473 r->sector_count -= n;
474 if (r->sector_count == 0) {
475 scsi_write_do_fua(r);
476 return;
477 } else {
478 scsi_init_iovec(r, SCSI_DMA_BUF_SIZE);
479 DPRINTF("Write complete tag=0x%x more=%zd\n", r->req.tag, r->qiov.size);
480 scsi_req_data(&r->req, r->qiov.size);
481 }
482
483done:
484 scsi_req_unref(&r->req);
485}
486
487static void scsi_write_complete(void * opaque, int ret)
488{
489 SCSIDiskReq *r = (SCSIDiskReq *)opaque;
490 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
491
492 assert (r->req.aiocb != NULL);
493 r->req.aiocb = NULL;
494
495 if (ret < 0) {
496 block_acct_failed(blk_get_stats(s->qdev.conf.blk), &r->acct);
497 } else {
498 block_acct_done(blk_get_stats(s->qdev.conf.blk), &r->acct);
499 }
500 scsi_write_complete_noio(r, ret);
501}
502
503static void scsi_write_data(SCSIRequest *req)
504{
505 SCSIDiskReq *r = DO_UPCAST(SCSIDiskReq, req, req);
506 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
507 uint32_t n;
508
509
510 assert(r->req.aiocb == NULL);
511
512
513 scsi_req_ref(&r->req);
514 if (r->req.cmd.mode != SCSI_XFER_TO_DEV) {
515 DPRINTF("Data transfer direction invalid\n");
516 scsi_write_complete_noio(r, -EINVAL);
517 return;
518 }
519
520 if (!r->req.sg && !r->qiov.size) {
521
522 r->started = true;
523 scsi_write_complete_noio(r, 0);
524 return;
525 }
526 if (s->tray_open) {
527 scsi_write_complete_noio(r, -ENOMEDIUM);
528 return;
529 }
530
531 if (r->req.cmd.buf[0] == VERIFY_10 || r->req.cmd.buf[0] == VERIFY_12 ||
532 r->req.cmd.buf[0] == VERIFY_16) {
533 if (r->req.sg) {
534 scsi_dma_complete_noio(r, 0);
535 } else {
536 scsi_write_complete_noio(r, 0);
537 }
538 return;
539 }
540
541 if (r->req.sg) {
542 dma_acct_start(s->qdev.conf.blk, &r->acct, r->req.sg, BLOCK_ACCT_WRITE);
543 r->req.resid -= r->req.sg->size;
544 r->req.aiocb = dma_blk_write(s->qdev.conf.blk, r->req.sg, r->sector,
545 scsi_dma_complete, r);
546 } else {
547 n = r->qiov.size / 512;
548 block_acct_start(blk_get_stats(s->qdev.conf.blk), &r->acct,
549 n * BDRV_SECTOR_SIZE, BLOCK_ACCT_WRITE);
550 r->req.aiocb = blk_aio_writev(s->qdev.conf.blk, r->sector, &r->qiov, n,
551 scsi_write_complete, r);
552 }
553}
554
555
556static uint8_t *scsi_get_buf(SCSIRequest *req)
557{
558 SCSIDiskReq *r = DO_UPCAST(SCSIDiskReq, req, req);
559
560 return (uint8_t *)r->iov.iov_base;
561}
562
563static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf)
564{
565 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev);
566 int buflen = 0;
567 int start;
568
569 if (req->cmd.buf[1] & 0x1) {
570
571 uint8_t page_code = req->cmd.buf[2];
572
573 outbuf[buflen++] = s->qdev.type & 0x1f;
574 outbuf[buflen++] = page_code ;
575 outbuf[buflen++] = 0x00;
576 outbuf[buflen++] = 0x00;
577 start = buflen;
578
579 switch (page_code) {
580 case 0x00:
581 {
582 DPRINTF("Inquiry EVPD[Supported pages] "
583 "buffer size %zd\n", req->cmd.xfer);
584 outbuf[buflen++] = 0x00;
585 if (s->serial) {
586 outbuf[buflen++] = 0x80;
587 }
588 outbuf[buflen++] = 0x83;
589 if (s->qdev.type == TYPE_DISK) {
590 outbuf[buflen++] = 0xb0;
591 outbuf[buflen++] = 0xb2;
592 }
593 break;
594 }
595 case 0x80:
596 {
597 int l;
598
599 if (!s->serial) {
600 DPRINTF("Inquiry (EVPD[Serial number] not supported\n");
601 return -1;
602 }
603
604 l = strlen(s->serial);
605 if (l > 20) {
606 l = 20;
607 }
608
609 DPRINTF("Inquiry EVPD[Serial number] "
610 "buffer size %zd\n", req->cmd.xfer);
611 memcpy(outbuf+buflen, s->serial, l);
612 buflen += l;
613 break;
614 }
615
616 case 0x83:
617 {
618 const char *str = s->serial ?: blk_name(s->qdev.conf.blk);
619 int max_len = s->serial ? 20 : 255 - 8;
620 int id_len = strlen(str);
621
622 if (id_len > max_len) {
623 id_len = max_len;
624 }
625 DPRINTF("Inquiry EVPD[Device identification] "
626 "buffer size %zd\n", req->cmd.xfer);
627
628 outbuf[buflen++] = 0x2;
629 outbuf[buflen++] = 0;
630 outbuf[buflen++] = 0;
631 outbuf[buflen++] = id_len;
632 memcpy(outbuf+buflen, str, id_len);
633 buflen += id_len;
634
635 if (s->qdev.wwn) {
636 outbuf[buflen++] = 0x1;
637 outbuf[buflen++] = 0x3;
638 outbuf[buflen++] = 0;
639 outbuf[buflen++] = 8;
640 stq_be_p(&outbuf[buflen], s->qdev.wwn);
641 buflen += 8;
642 }
643
644 if (s->qdev.port_wwn) {
645 outbuf[buflen++] = 0x61;
646 outbuf[buflen++] = 0x93;
647 outbuf[buflen++] = 0;
648 outbuf[buflen++] = 8;
649 stq_be_p(&outbuf[buflen], s->qdev.port_wwn);
650 buflen += 8;
651 }
652
653 if (s->port_index) {
654 outbuf[buflen++] = 0x61;
655 outbuf[buflen++] = 0x94;
656 outbuf[buflen++] = 0;
657 outbuf[buflen++] = 4;
658 stw_be_p(&outbuf[buflen + 2], s->port_index);
659 buflen += 4;
660 }
661 break;
662 }
663 case 0xb0:
664 {
665 unsigned int unmap_sectors =
666 s->qdev.conf.discard_granularity / s->qdev.blocksize;
667 unsigned int min_io_size =
668 s->qdev.conf.min_io_size / s->qdev.blocksize;
669 unsigned int opt_io_size =
670 s->qdev.conf.opt_io_size / s->qdev.blocksize;
671 unsigned int max_unmap_sectors =
672 s->max_unmap_size / s->qdev.blocksize;
673 unsigned int max_io_sectors =
674 s->max_io_size / s->qdev.blocksize;
675
676 if (s->qdev.type == TYPE_ROM) {
677 DPRINTF("Inquiry (EVPD[%02X] not supported for CDROM\n",
678 page_code);
679 return -1;
680 }
681
682 buflen = 0x40;
683 memset(outbuf + 4, 0, buflen - 4);
684
685 outbuf[4] = 0x1;
686
687
688 outbuf[6] = (min_io_size >> 8) & 0xff;
689 outbuf[7] = min_io_size & 0xff;
690
691
692 outbuf[8] = (max_io_sectors >> 24) & 0xff;
693 outbuf[9] = (max_io_sectors >> 16) & 0xff;
694 outbuf[10] = (max_io_sectors >> 8) & 0xff;
695 outbuf[11] = max_io_sectors & 0xff;
696
697
698 outbuf[12] = (opt_io_size >> 24) & 0xff;
699 outbuf[13] = (opt_io_size >> 16) & 0xff;
700 outbuf[14] = (opt_io_size >> 8) & 0xff;
701 outbuf[15] = opt_io_size & 0xff;
702
703
704 outbuf[20] = (max_unmap_sectors >> 24) & 0xff;
705 outbuf[21] = (max_unmap_sectors >> 16) & 0xff;
706 outbuf[22] = (max_unmap_sectors >> 8) & 0xff;
707 outbuf[23] = max_unmap_sectors & 0xff;
708
709
710 outbuf[24] = 0;
711 outbuf[25] = 0;
712 outbuf[26] = 0;
713 outbuf[27] = 255;
714
715
716 outbuf[28] = (unmap_sectors >> 24) & 0xff;
717 outbuf[29] = (unmap_sectors >> 16) & 0xff;
718 outbuf[30] = (unmap_sectors >> 8) & 0xff;
719 outbuf[31] = unmap_sectors & 0xff;
720
721
722 outbuf[36] = 0;
723 outbuf[37] = 0;
724 outbuf[38] = 0;
725 outbuf[39] = 0;
726
727 outbuf[40] = (max_io_sectors >> 24) & 0xff;
728 outbuf[41] = (max_io_sectors >> 16) & 0xff;
729 outbuf[42] = (max_io_sectors >> 8) & 0xff;
730 outbuf[43] = max_io_sectors & 0xff;
731 break;
732 }
733 case 0xb2:
734 {
735 buflen = 8;
736 outbuf[4] = 0;
737 outbuf[5] = 0xe0;
738 outbuf[6] = s->qdev.conf.discard_granularity ? 2 : 1;
739 outbuf[7] = 0;
740 break;
741 }
742 default:
743 return -1;
744 }
745
746 assert(buflen - start <= 255);
747 outbuf[start - 1] = buflen - start;
748 return buflen;
749 }
750
751
752 if (req->cmd.buf[2] != 0) {
753 return -1;
754 }
755
756
757 buflen = req->cmd.xfer;
758 if (buflen > SCSI_MAX_INQUIRY_LEN) {
759 buflen = SCSI_MAX_INQUIRY_LEN;
760 }
761
762 outbuf[0] = s->qdev.type & 0x1f;
763 outbuf[1] = (s->features & (1 << SCSI_DISK_F_REMOVABLE)) ? 0x80 : 0;
764
765 strpadcpy((char *) &outbuf[16], 16, s->product, ' ');
766 strpadcpy((char *) &outbuf[8], 8, s->vendor, ' ');
767
768 memset(&outbuf[32], 0, 4);
769 memcpy(&outbuf[32], s->version, MIN(4, strlen(s->version)));
770
771
772
773
774
775
776 outbuf[2] = 5;
777 outbuf[3] = 2 | 0x10;
778
779 if (buflen > 36) {
780 outbuf[4] = buflen - 5;
781 } else {
782
783
784 outbuf[4] = 36 - 5;
785 }
786
787
788 outbuf[7] = 0x10 | (req->bus->info->tcq ? 0x02 : 0);
789 return buflen;
790}
791
792static inline bool media_is_dvd(SCSIDiskState *s)
793{
794 uint64_t nb_sectors;
795 if (s->qdev.type != TYPE_ROM) {
796 return false;
797 }
798 if (!blk_is_inserted(s->qdev.conf.blk)) {
799 return false;
800 }
801 if (s->tray_open) {
802 return false;
803 }
804 blk_get_geometry(s->qdev.conf.blk, &nb_sectors);
805 return nb_sectors > CD_MAX_SECTORS;
806}
807
808static inline bool media_is_cd(SCSIDiskState *s)
809{
810 uint64_t nb_sectors;
811 if (s->qdev.type != TYPE_ROM) {
812 return false;
813 }
814 if (!blk_is_inserted(s->qdev.conf.blk)) {
815 return false;
816 }
817 if (s->tray_open) {
818 return false;
819 }
820 blk_get_geometry(s->qdev.conf.blk, &nb_sectors);
821 return nb_sectors <= CD_MAX_SECTORS;
822}
823
824static int scsi_read_disc_information(SCSIDiskState *s, SCSIDiskReq *r,
825 uint8_t *outbuf)
826{
827 uint8_t type = r->req.cmd.buf[1] & 7;
828
829 if (s->qdev.type != TYPE_ROM) {
830 return -1;
831 }
832
833
834 if (type != 0) {
835 scsi_check_condition(r, SENSE_CODE(INVALID_FIELD));
836 return -1;
837 }
838
839 memset(outbuf, 0, 34);
840 outbuf[1] = 32;
841 outbuf[2] = 0xe;
842 outbuf[3] = 1;
843 outbuf[4] = 1;
844 outbuf[5] = 1;
845 outbuf[6] = 1;
846 outbuf[7] = 0x20;
847 outbuf[8] = 0x00;
848
849
850
851
852
853
854 return 34;
855}
856
857static int scsi_read_dvd_structure(SCSIDiskState *s, SCSIDiskReq *r,
858 uint8_t *outbuf)
859{
860 static const int rds_caps_size[5] = {
861 [0] = 2048 + 4,
862 [1] = 4 + 4,
863 [3] = 188 + 4,
864 [4] = 2048 + 4,
865 };
866
867 uint8_t media = r->req.cmd.buf[1];
868 uint8_t layer = r->req.cmd.buf[6];
869 uint8_t format = r->req.cmd.buf[7];
870 int size = -1;
871
872 if (s->qdev.type != TYPE_ROM) {
873 return -1;
874 }
875 if (media != 0) {
876 scsi_check_condition(r, SENSE_CODE(INVALID_FIELD));
877 return -1;
878 }
879
880 if (format != 0xff) {
881 if (s->tray_open || !blk_is_inserted(s->qdev.conf.blk)) {
882 scsi_check_condition(r, SENSE_CODE(NO_MEDIUM));
883 return -1;
884 }
885 if (media_is_cd(s)) {
886 scsi_check_condition(r, SENSE_CODE(INCOMPATIBLE_FORMAT));
887 return -1;
888 }
889 if (format >= ARRAY_SIZE(rds_caps_size)) {
890 return -1;
891 }
892 size = rds_caps_size[format];
893 memset(outbuf, 0, size);
894 }
895
896 switch (format) {
897 case 0x00: {
898
899 uint64_t nb_sectors;
900 if (layer != 0) {
901 goto fail;
902 }
903 blk_get_geometry(s->qdev.conf.blk, &nb_sectors);
904
905 outbuf[4] = 1;
906 outbuf[5] = 0xf;
907 outbuf[6] = 1;
908 outbuf[7] = 0;
909
910 stl_be_p(&outbuf[12], (nb_sectors >> 2) - 1);
911 stl_be_p(&outbuf[16], (nb_sectors >> 2) - 1);
912 break;
913 }
914
915 case 0x01:
916 break;
917
918 case 0x03:
919 return -1;
920
921 case 0x04:
922 break;
923
924 case 0xff: {
925 int i;
926 size = 4;
927 for (i = 0; i < ARRAY_SIZE(rds_caps_size); i++) {
928 if (!rds_caps_size[i]) {
929 continue;
930 }
931 outbuf[size] = i;
932 outbuf[size + 1] = 0x40;
933 stw_be_p(&outbuf[size + 2], rds_caps_size[i]);
934 size += 4;
935 }
936 break;
937 }
938
939 default:
940 return -1;
941 }
942
943
944 stw_be_p(outbuf, size - 2);
945 return size;
946
947fail:
948 return -1;
949}
950
951static int scsi_event_status_media(SCSIDiskState *s, uint8_t *outbuf)
952{
953 uint8_t event_code, media_status;
954
955 media_status = 0;
956 if (s->tray_open) {
957 media_status = MS_TRAY_OPEN;
958 } else if (blk_is_inserted(s->qdev.conf.blk)) {
959 media_status = MS_MEDIA_PRESENT;
960 }
961
962
963 event_code = MEC_NO_CHANGE;
964 if (media_status != MS_TRAY_OPEN) {
965 if (s->media_event) {
966 event_code = MEC_NEW_MEDIA;
967 s->media_event = false;
968 } else if (s->eject_request) {
969 event_code = MEC_EJECT_REQUESTED;
970 s->eject_request = false;
971 }
972 }
973
974 outbuf[0] = event_code;
975 outbuf[1] = media_status;
976
977
978 outbuf[2] = 0;
979 outbuf[3] = 0;
980 return 4;
981}
982
983static int scsi_get_event_status_notification(SCSIDiskState *s, SCSIDiskReq *r,
984 uint8_t *outbuf)
985{
986 int size;
987 uint8_t *buf = r->req.cmd.buf;
988 uint8_t notification_class_request = buf[4];
989 if (s->qdev.type != TYPE_ROM) {
990 return -1;
991 }
992 if ((buf[1] & 1) == 0) {
993
994 return -1;
995 }
996
997 size = 4;
998 outbuf[0] = outbuf[1] = 0;
999 outbuf[3] = 1 << GESN_MEDIA;
1000 if (notification_class_request & (1 << GESN_MEDIA)) {
1001 outbuf[2] = GESN_MEDIA;
1002 size += scsi_event_status_media(s, &outbuf[size]);
1003 } else {
1004 outbuf[2] = 0x80;
1005 }
1006 stw_be_p(outbuf, size - 4);
1007 return size;
1008}
1009
1010static int scsi_get_configuration(SCSIDiskState *s, uint8_t *outbuf)
1011{
1012 int current;
1013
1014 if (s->qdev.type != TYPE_ROM) {
1015 return -1;
1016 }
1017
1018 if (media_is_dvd(s)) {
1019 current = MMC_PROFILE_DVD_ROM;
1020 } else if (media_is_cd(s)) {
1021 current = MMC_PROFILE_CD_ROM;
1022 } else {
1023 current = MMC_PROFILE_NONE;
1024 }
1025
1026 memset(outbuf, 0, 40);
1027 stl_be_p(&outbuf[0], 36);
1028 stw_be_p(&outbuf[6], current);
1029
1030 outbuf[10] = 0x03;
1031 outbuf[11] = 8;
1032 stw_be_p(&outbuf[12], MMC_PROFILE_DVD_ROM);
1033 outbuf[14] = (current == MMC_PROFILE_DVD_ROM);
1034 stw_be_p(&outbuf[16], MMC_PROFILE_CD_ROM);
1035 outbuf[18] = (current == MMC_PROFILE_CD_ROM);
1036
1037 stw_be_p(&outbuf[20], 1);
1038 outbuf[22] = 0x08 | 0x03;
1039 outbuf[23] = 8;
1040 stl_be_p(&outbuf[24], 1);
1041 outbuf[28] = 1;
1042
1043 stw_be_p(&outbuf[32], 3);
1044 outbuf[34] = 0x08 | 0x03;
1045 outbuf[35] = 4;
1046 outbuf[36] = 0x39;
1047
1048
1049 return 40;
1050}
1051
1052static int scsi_emulate_mechanism_status(SCSIDiskState *s, uint8_t *outbuf)
1053{
1054 if (s->qdev.type != TYPE_ROM) {
1055 return -1;
1056 }
1057 memset(outbuf, 0, 8);
1058 outbuf[5] = 1;
1059 return 8;
1060}
1061
1062static int mode_sense_page(SCSIDiskState *s, int page, uint8_t **p_outbuf,
1063 int page_control)
1064{
1065 static const int mode_sense_valid[0x3f] = {
1066 [MODE_PAGE_HD_GEOMETRY] = (1 << TYPE_DISK),
1067 [MODE_PAGE_FLEXIBLE_DISK_GEOMETRY] = (1 << TYPE_DISK),
1068 [MODE_PAGE_CACHING] = (1 << TYPE_DISK) | (1 << TYPE_ROM),
1069 [MODE_PAGE_R_W_ERROR] = (1 << TYPE_DISK) | (1 << TYPE_ROM),
1070 [MODE_PAGE_AUDIO_CTL] = (1 << TYPE_ROM),
1071 [MODE_PAGE_CAPABILITIES] = (1 << TYPE_ROM),
1072 };
1073
1074 uint8_t *p = *p_outbuf + 2;
1075 int length;
1076
1077 if ((mode_sense_valid[page] & (1 << s->qdev.type)) == 0) {
1078 return -1;
1079 }
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093 switch (page) {
1094 case MODE_PAGE_HD_GEOMETRY:
1095 length = 0x16;
1096 if (page_control == 1) {
1097 break;
1098 }
1099
1100 p[0] = (s->qdev.conf.cyls >> 16) & 0xff;
1101 p[1] = (s->qdev.conf.cyls >> 8) & 0xff;
1102 p[2] = s->qdev.conf.cyls & 0xff;
1103 p[3] = s->qdev.conf.heads & 0xff;
1104
1105 p[4] = (s->qdev.conf.cyls >> 16) & 0xff;
1106 p[5] = (s->qdev.conf.cyls >> 8) & 0xff;
1107 p[6] = s->qdev.conf.cyls & 0xff;
1108
1109 p[7] = (s->qdev.conf.cyls >> 16) & 0xff;
1110 p[8] = (s->qdev.conf.cyls >> 8) & 0xff;
1111 p[9] = s->qdev.conf.cyls & 0xff;
1112
1113 p[10] = 0;
1114 p[11] = 200;
1115
1116 p[12] = 0xff;
1117 p[13] = 0xff;
1118 p[14] = 0xff;
1119
1120 p[18] = (5400 >> 8) & 0xff;
1121 p[19] = 5400 & 0xff;
1122 break;
1123
1124 case MODE_PAGE_FLEXIBLE_DISK_GEOMETRY:
1125 length = 0x1e;
1126 if (page_control == 1) {
1127 break;
1128 }
1129
1130 p[0] = 5000 >> 8;
1131 p[1] = 5000 & 0xff;
1132
1133 p[2] = s->qdev.conf.heads & 0xff;
1134 p[3] = s->qdev.conf.secs & 0xff;
1135 p[4] = s->qdev.blocksize >> 8;
1136 p[6] = (s->qdev.conf.cyls >> 8) & 0xff;
1137 p[7] = s->qdev.conf.cyls & 0xff;
1138
1139 p[8] = (s->qdev.conf.cyls >> 8) & 0xff;
1140 p[9] = s->qdev.conf.cyls & 0xff;
1141
1142 p[10] = (s->qdev.conf.cyls >> 8) & 0xff;
1143 p[11] = s->qdev.conf.cyls & 0xff;
1144
1145 p[12] = 0;
1146 p[13] = 1;
1147
1148 p[14] = 1;
1149
1150 p[15] = 0;
1151 p[16] = 1;
1152
1153 p[17] = 1;
1154
1155 p[18] = 1;
1156
1157 p[26] = (5400 >> 8) & 0xff;
1158 p[27] = 5400 & 0xff;
1159 break;
1160
1161 case MODE_PAGE_CACHING:
1162 length = 0x12;
1163 if (page_control == 1 ||
1164 blk_enable_write_cache(s->qdev.conf.blk)) {
1165 p[0] = 4;
1166 }
1167 break;
1168
1169 case MODE_PAGE_R_W_ERROR:
1170 length = 10;
1171 if (page_control == 1) {
1172 break;
1173 }
1174 p[0] = 0x80;
1175 if (s->qdev.type == TYPE_ROM) {
1176 p[1] = 0x20;
1177 }
1178 break;
1179
1180 case MODE_PAGE_AUDIO_CTL:
1181 length = 14;
1182 break;
1183
1184 case MODE_PAGE_CAPABILITIES:
1185 length = 0x14;
1186 if (page_control == 1) {
1187 break;
1188 }
1189
1190 p[0] = 0x3b;
1191 p[1] = 0;
1192 p[2] = 0x7f;
1193
1194 p[3] = 0xff;
1195
1196
1197 p[4] = 0x2d | (s->tray_locked ? 2 : 0);
1198
1199 p[5] = 0;
1200
1201 p[6] = (50 * 176) >> 8;
1202 p[7] = (50 * 176) & 0xff;
1203 p[8] = 2 >> 8;
1204 p[9] = 2 & 0xff;
1205 p[10] = 2048 >> 8;
1206 p[11] = 2048 & 0xff;
1207 p[12] = (16 * 176) >> 8;
1208 p[13] = (16 * 176) & 0xff;
1209 p[16] = (16 * 176) >> 8;
1210 p[17] = (16 * 176) & 0xff;
1211 p[18] = (16 * 176) >> 8;
1212 p[19] = (16 * 176) & 0xff;
1213 break;
1214
1215 default:
1216 return -1;
1217 }
1218
1219 assert(length < 256);
1220 (*p_outbuf)[0] = page;
1221 (*p_outbuf)[1] = length;
1222 *p_outbuf += length + 2;
1223 return length + 2;
1224}
1225
1226static int scsi_disk_emulate_mode_sense(SCSIDiskReq *r, uint8_t *outbuf)
1227{
1228 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
1229 uint64_t nb_sectors;
1230 bool dbd;
1231 int page, buflen, ret, page_control;
1232 uint8_t *p;
1233 uint8_t dev_specific_param;
1234
1235 dbd = (r->req.cmd.buf[1] & 0x8) != 0;
1236 page = r->req.cmd.buf[2] & 0x3f;
1237 page_control = (r->req.cmd.buf[2] & 0xc0) >> 6;
1238 DPRINTF("Mode Sense(%d) (page %d, xfer %zd, page_control %d)\n",
1239 (r->req.cmd.buf[0] == MODE_SENSE) ? 6 : 10, page, r->req.cmd.xfer, page_control);
1240 memset(outbuf, 0, r->req.cmd.xfer);
1241 p = outbuf;
1242
1243 if (s->qdev.type == TYPE_DISK) {
1244 dev_specific_param = s->features & (1 << SCSI_DISK_F_DPOFUA) ? 0x10 : 0;
1245 if (blk_is_read_only(s->qdev.conf.blk)) {
1246 dev_specific_param |= 0x80;
1247 }
1248 } else {
1249
1250
1251 dev_specific_param = 0x00;
1252 dbd = true;
1253 }
1254
1255 if (r->req.cmd.buf[0] == MODE_SENSE) {
1256 p[1] = 0;
1257 p[2] = dev_specific_param;
1258 p[3] = 0;
1259 p += 4;
1260 } else {
1261 p[2] = 0;
1262 p[3] = dev_specific_param;
1263 p[6] = p[7] = 0;
1264 p += 8;
1265 }
1266
1267 blk_get_geometry(s->qdev.conf.blk, &nb_sectors);
1268 if (!dbd && nb_sectors) {
1269 if (r->req.cmd.buf[0] == MODE_SENSE) {
1270 outbuf[3] = 8;
1271 } else {
1272 outbuf[7] = 8;
1273 }
1274 nb_sectors /= (s->qdev.blocksize / 512);
1275 if (nb_sectors > 0xffffff) {
1276 nb_sectors = 0;
1277 }
1278 p[0] = 0;
1279 p[1] = (nb_sectors >> 16) & 0xff;
1280 p[2] = (nb_sectors >> 8) & 0xff;
1281 p[3] = nb_sectors & 0xff;
1282 p[4] = 0;
1283 p[5] = 0;
1284 p[6] = s->qdev.blocksize >> 8;
1285 p[7] = 0;
1286 p += 8;
1287 }
1288
1289 if (page_control == 3) {
1290
1291 scsi_check_condition(r, SENSE_CODE(SAVING_PARAMS_NOT_SUPPORTED));
1292 return -1;
1293 }
1294
1295 if (page == 0x3f) {
1296 for (page = 0; page <= 0x3e; page++) {
1297 mode_sense_page(s, page, &p, page_control);
1298 }
1299 } else {
1300 ret = mode_sense_page(s, page, &p, page_control);
1301 if (ret == -1) {
1302 return -1;
1303 }
1304 }
1305
1306 buflen = p - outbuf;
1307
1308
1309
1310
1311
1312 if (r->req.cmd.buf[0] == MODE_SENSE) {
1313 outbuf[0] = buflen - 1;
1314 } else {
1315 outbuf[0] = ((buflen - 2) >> 8) & 0xff;
1316 outbuf[1] = (buflen - 2) & 0xff;
1317 }
1318 return buflen;
1319}
1320
1321static int scsi_disk_emulate_read_toc(SCSIRequest *req, uint8_t *outbuf)
1322{
1323 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev);
1324 int start_track, format, msf, toclen;
1325 uint64_t nb_sectors;
1326
1327 msf = req->cmd.buf[1] & 2;
1328 format = req->cmd.buf[2] & 0xf;
1329 start_track = req->cmd.buf[6];
1330 blk_get_geometry(s->qdev.conf.blk, &nb_sectors);
1331 DPRINTF("Read TOC (track %d format %d msf %d)\n", start_track, format, msf >> 1);
1332 nb_sectors /= s->qdev.blocksize / 512;
1333 switch (format) {
1334 case 0:
1335 toclen = cdrom_read_toc(nb_sectors, outbuf, msf, start_track);
1336 break;
1337 case 1:
1338
1339 toclen = 12;
1340 memset(outbuf, 0, 12);
1341 outbuf[1] = 0x0a;
1342 outbuf[2] = 0x01;
1343 outbuf[3] = 0x01;
1344 break;
1345 case 2:
1346 toclen = cdrom_read_toc_raw(nb_sectors, outbuf, msf, start_track);
1347 break;
1348 default:
1349 return -1;
1350 }
1351 return toclen;
1352}
1353
1354static int scsi_disk_emulate_start_stop(SCSIDiskReq *r)
1355{
1356 SCSIRequest *req = &r->req;
1357 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev);
1358 bool start = req->cmd.buf[4] & 1;
1359 bool loej = req->cmd.buf[4] & 2;
1360 int pwrcnd = req->cmd.buf[4] & 0xf0;
1361
1362 if (pwrcnd) {
1363
1364 return 0;
1365 }
1366
1367 if ((s->features & (1 << SCSI_DISK_F_REMOVABLE)) && loej) {
1368 if (!start && !s->tray_open && s->tray_locked) {
1369 scsi_check_condition(r,
1370 blk_is_inserted(s->qdev.conf.blk)
1371 ? SENSE_CODE(ILLEGAL_REQ_REMOVAL_PREVENTED)
1372 : SENSE_CODE(NOT_READY_REMOVAL_PREVENTED));
1373 return -1;
1374 }
1375
1376 if (s->tray_open != !start) {
1377 blk_eject(s->qdev.conf.blk, !start);
1378 s->tray_open = !start;
1379 }
1380 }
1381 return 0;
1382}
1383
1384static void scsi_disk_emulate_read_data(SCSIRequest *req)
1385{
1386 SCSIDiskReq *r = DO_UPCAST(SCSIDiskReq, req, req);
1387 int buflen = r->iov.iov_len;
1388
1389 if (buflen) {
1390 DPRINTF("Read buf_len=%d\n", buflen);
1391 r->iov.iov_len = 0;
1392 r->started = true;
1393 scsi_req_data(&r->req, buflen);
1394 return;
1395 }
1396
1397
1398 scsi_req_complete(&r->req, GOOD);
1399}
1400
1401static int scsi_disk_check_mode_select(SCSIDiskState *s, int page,
1402 uint8_t *inbuf, int inlen)
1403{
1404 uint8_t mode_current[SCSI_MAX_MODE_LEN];
1405 uint8_t mode_changeable[SCSI_MAX_MODE_LEN];
1406 uint8_t *p;
1407 int len, expected_len, changeable_len, i;
1408
1409
1410
1411
1412 expected_len = inlen + 2;
1413 if (expected_len > SCSI_MAX_MODE_LEN) {
1414 return -1;
1415 }
1416
1417 p = mode_current;
1418 memset(mode_current, 0, inlen + 2);
1419 len = mode_sense_page(s, page, &p, 0);
1420 if (len < 0 || len != expected_len) {
1421 return -1;
1422 }
1423
1424 p = mode_changeable;
1425 memset(mode_changeable, 0, inlen + 2);
1426 changeable_len = mode_sense_page(s, page, &p, 1);
1427 assert(changeable_len == len);
1428
1429
1430
1431
1432 for (i = 2; i < len; i++) {
1433 if (((mode_current[i] ^ inbuf[i - 2]) & ~mode_changeable[i]) != 0) {
1434 return -1;
1435 }
1436 }
1437 return 0;
1438}
1439
1440static void scsi_disk_apply_mode_select(SCSIDiskState *s, int page, uint8_t *p)
1441{
1442 switch (page) {
1443 case MODE_PAGE_CACHING:
1444 blk_set_enable_write_cache(s->qdev.conf.blk, (p[0] & 4) != 0);
1445 break;
1446
1447 default:
1448 break;
1449 }
1450}
1451
1452static int mode_select_pages(SCSIDiskReq *r, uint8_t *p, int len, bool change)
1453{
1454 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
1455
1456 while (len > 0) {
1457 int page, subpage, page_len;
1458
1459
1460 page = p[0] & 0x3f;
1461 if (p[0] & 0x40) {
1462 if (len < 4) {
1463 goto invalid_param_len;
1464 }
1465 subpage = p[1];
1466 page_len = lduw_be_p(&p[2]);
1467 p += 4;
1468 len -= 4;
1469 } else {
1470 if (len < 2) {
1471 goto invalid_param_len;
1472 }
1473 subpage = 0;
1474 page_len = p[1];
1475 p += 2;
1476 len -= 2;
1477 }
1478
1479 if (subpage) {
1480 goto invalid_param;
1481 }
1482 if (page_len > len) {
1483 goto invalid_param_len;
1484 }
1485
1486 if (!change) {
1487 if (scsi_disk_check_mode_select(s, page, p, page_len) < 0) {
1488 goto invalid_param;
1489 }
1490 } else {
1491 scsi_disk_apply_mode_select(s, page, p);
1492 }
1493
1494 p += page_len;
1495 len -= page_len;
1496 }
1497 return 0;
1498
1499invalid_param:
1500 scsi_check_condition(r, SENSE_CODE(INVALID_PARAM));
1501 return -1;
1502
1503invalid_param_len:
1504 scsi_check_condition(r, SENSE_CODE(INVALID_PARAM_LEN));
1505 return -1;
1506}
1507
1508static void scsi_disk_emulate_mode_select(SCSIDiskReq *r, uint8_t *inbuf)
1509{
1510 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
1511 uint8_t *p = inbuf;
1512 int cmd = r->req.cmd.buf[0];
1513 int len = r->req.cmd.xfer;
1514 int hdr_len = (cmd == MODE_SELECT ? 4 : 8);
1515 int bd_len;
1516 int pass;
1517
1518
1519 if ((r->req.cmd.buf[1] & 0x11) != 0x10) {
1520 goto invalid_field;
1521 }
1522
1523 if (len < hdr_len) {
1524 goto invalid_param_len;
1525 }
1526
1527 bd_len = (cmd == MODE_SELECT ? p[3] : lduw_be_p(&p[6]));
1528 len -= hdr_len;
1529 p += hdr_len;
1530 if (len < bd_len) {
1531 goto invalid_param_len;
1532 }
1533 if (bd_len != 0 && bd_len != 8) {
1534 goto invalid_param;
1535 }
1536
1537 len -= bd_len;
1538 p += bd_len;
1539
1540
1541 for (pass = 0; pass < 2; pass++) {
1542 if (mode_select_pages(r, p, len, pass == 1) < 0) {
1543 assert(pass == 0);
1544 return;
1545 }
1546 }
1547 if (!blk_enable_write_cache(s->qdev.conf.blk)) {
1548
1549 scsi_req_ref(&r->req);
1550 block_acct_start(blk_get_stats(s->qdev.conf.blk), &r->acct, 0,
1551 BLOCK_ACCT_FLUSH);
1552 r->req.aiocb = blk_aio_flush(s->qdev.conf.blk, scsi_aio_complete, r);
1553 return;
1554 }
1555
1556 scsi_req_complete(&r->req, GOOD);
1557 return;
1558
1559invalid_param:
1560 scsi_check_condition(r, SENSE_CODE(INVALID_PARAM));
1561 return;
1562
1563invalid_param_len:
1564 scsi_check_condition(r, SENSE_CODE(INVALID_PARAM_LEN));
1565 return;
1566
1567invalid_field:
1568 scsi_check_condition(r, SENSE_CODE(INVALID_FIELD));
1569}
1570
1571static inline bool check_lba_range(SCSIDiskState *s,
1572 uint64_t sector_num, uint32_t nb_sectors)
1573{
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583 return (sector_num <= sector_num + nb_sectors &&
1584 sector_num + nb_sectors <= s->qdev.max_lba + 1);
1585}
1586
1587typedef struct UnmapCBData {
1588 SCSIDiskReq *r;
1589 uint8_t *inbuf;
1590 int count;
1591} UnmapCBData;
1592
1593static void scsi_unmap_complete(void *opaque, int ret);
1594
1595static void scsi_unmap_complete_noio(UnmapCBData *data, int ret)
1596{
1597 SCSIDiskReq *r = data->r;
1598 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
1599 uint64_t sector_num;
1600 uint32_t nb_sectors;
1601
1602 assert(r->req.aiocb == NULL);
1603
1604 if (r->req.io_canceled) {
1605 scsi_req_cancel_complete(&r->req);
1606 goto done;
1607 }
1608
1609 if (ret < 0) {
1610 if (scsi_handle_rw_error(r, -ret, false)) {
1611 goto done;
1612 }
1613 }
1614
1615 if (data->count > 0) {
1616 sector_num = ldq_be_p(&data->inbuf[0]);
1617 nb_sectors = ldl_be_p(&data->inbuf[8]) & 0xffffffffULL;
1618 if (!check_lba_range(s, sector_num, nb_sectors)) {
1619 scsi_check_condition(r, SENSE_CODE(LBA_OUT_OF_RANGE));
1620 goto done;
1621 }
1622
1623 r->req.aiocb = blk_aio_discard(s->qdev.conf.blk,
1624 sector_num * (s->qdev.blocksize / 512),
1625 nb_sectors * (s->qdev.blocksize / 512),
1626 scsi_unmap_complete, data);
1627 data->count--;
1628 data->inbuf += 16;
1629 return;
1630 }
1631
1632 scsi_req_complete(&r->req, GOOD);
1633
1634done:
1635 scsi_req_unref(&r->req);
1636 g_free(data);
1637}
1638
1639static void scsi_unmap_complete(void *opaque, int ret)
1640{
1641 UnmapCBData *data = opaque;
1642 SCSIDiskReq *r = data->r;
1643
1644 assert(r->req.aiocb != NULL);
1645 r->req.aiocb = NULL;
1646
1647 scsi_unmap_complete_noio(data, ret);
1648}
1649
1650static void scsi_disk_emulate_unmap(SCSIDiskReq *r, uint8_t *inbuf)
1651{
1652 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
1653 uint8_t *p = inbuf;
1654 int len = r->req.cmd.xfer;
1655 UnmapCBData *data;
1656
1657
1658 if (r->req.cmd.buf[1] & 0x1) {
1659 goto invalid_field;
1660 }
1661
1662 if (len < 8) {
1663 goto invalid_param_len;
1664 }
1665 if (len < lduw_be_p(&p[0]) + 2) {
1666 goto invalid_param_len;
1667 }
1668 if (len < lduw_be_p(&p[2]) + 8) {
1669 goto invalid_param_len;
1670 }
1671 if (lduw_be_p(&p[2]) & 15) {
1672 goto invalid_param_len;
1673 }
1674
1675 if (blk_is_read_only(s->qdev.conf.blk)) {
1676 scsi_check_condition(r, SENSE_CODE(WRITE_PROTECTED));
1677 return;
1678 }
1679
1680 data = g_new0(UnmapCBData, 1);
1681 data->r = r;
1682 data->inbuf = &p[8];
1683 data->count = lduw_be_p(&p[2]) >> 4;
1684
1685
1686 scsi_req_ref(&r->req);
1687 scsi_unmap_complete_noio(data, 0);
1688 return;
1689
1690invalid_param_len:
1691 scsi_check_condition(r, SENSE_CODE(INVALID_PARAM_LEN));
1692 return;
1693
1694invalid_field:
1695 scsi_check_condition(r, SENSE_CODE(INVALID_FIELD));
1696}
1697
1698typedef struct WriteSameCBData {
1699 SCSIDiskReq *r;
1700 int64_t sector;
1701 int nb_sectors;
1702 QEMUIOVector qiov;
1703 struct iovec iov;
1704} WriteSameCBData;
1705
1706static void scsi_write_same_complete(void *opaque, int ret)
1707{
1708 WriteSameCBData *data = opaque;
1709 SCSIDiskReq *r = data->r;
1710 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
1711
1712 assert(r->req.aiocb != NULL);
1713 r->req.aiocb = NULL;
1714 if (r->req.io_canceled) {
1715 scsi_req_cancel_complete(&r->req);
1716 goto done;
1717 }
1718
1719 if (ret < 0) {
1720 if (scsi_handle_rw_error(r, -ret, true)) {
1721 goto done;
1722 }
1723 }
1724
1725 block_acct_done(blk_get_stats(s->qdev.conf.blk), &r->acct);
1726
1727 data->nb_sectors -= data->iov.iov_len / 512;
1728 data->sector += data->iov.iov_len / 512;
1729 data->iov.iov_len = MIN(data->nb_sectors * 512, data->iov.iov_len);
1730 if (data->iov.iov_len) {
1731 block_acct_start(blk_get_stats(s->qdev.conf.blk), &r->acct,
1732 data->iov.iov_len, BLOCK_ACCT_WRITE);
1733
1734
1735
1736 qemu_iovec_init_external(&data->qiov, &data->iov, 1);
1737 r->req.aiocb = blk_aio_writev(s->qdev.conf.blk, data->sector,
1738 &data->qiov, data->iov.iov_len / 512,
1739 scsi_write_same_complete, data);
1740 return;
1741 }
1742
1743 scsi_req_complete(&r->req, GOOD);
1744
1745done:
1746 scsi_req_unref(&r->req);
1747 qemu_vfree(data->iov.iov_base);
1748 g_free(data);
1749}
1750
1751static void scsi_disk_emulate_write_same(SCSIDiskReq *r, uint8_t *inbuf)
1752{
1753 SCSIRequest *req = &r->req;
1754 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev);
1755 uint32_t nb_sectors = scsi_data_cdb_xfer(r->req.cmd.buf);
1756 WriteSameCBData *data;
1757 uint8_t *buf;
1758 int i;
1759
1760
1761 if (nb_sectors == 0 || (req->cmd.buf[1] & 0x16)) {
1762 scsi_check_condition(r, SENSE_CODE(INVALID_FIELD));
1763 return;
1764 }
1765
1766 if (blk_is_read_only(s->qdev.conf.blk)) {
1767 scsi_check_condition(r, SENSE_CODE(WRITE_PROTECTED));
1768 return;
1769 }
1770 if (!check_lba_range(s, r->req.cmd.lba, nb_sectors)) {
1771 scsi_check_condition(r, SENSE_CODE(LBA_OUT_OF_RANGE));
1772 return;
1773 }
1774
1775 if (buffer_is_zero(inbuf, s->qdev.blocksize)) {
1776 int flags = (req->cmd.buf[1] & 0x8) ? BDRV_REQ_MAY_UNMAP : 0;
1777
1778
1779 scsi_req_ref(&r->req);
1780 block_acct_start(blk_get_stats(s->qdev.conf.blk), &r->acct,
1781 nb_sectors * s->qdev.blocksize,
1782 BLOCK_ACCT_WRITE);
1783 r->req.aiocb = blk_aio_write_zeroes(s->qdev.conf.blk,
1784 r->req.cmd.lba * (s->qdev.blocksize / 512),
1785 nb_sectors * (s->qdev.blocksize / 512),
1786 flags, scsi_aio_complete, r);
1787 return;
1788 }
1789
1790 data = g_new0(WriteSameCBData, 1);
1791 data->r = r;
1792 data->sector = r->req.cmd.lba * (s->qdev.blocksize / 512);
1793 data->nb_sectors = nb_sectors * (s->qdev.blocksize / 512);
1794 data->iov.iov_len = MIN(data->nb_sectors * 512, SCSI_WRITE_SAME_MAX);
1795 data->iov.iov_base = buf = blk_blockalign(s->qdev.conf.blk,
1796 data->iov.iov_len);
1797 qemu_iovec_init_external(&data->qiov, &data->iov, 1);
1798
1799 for (i = 0; i < data->iov.iov_len; i += s->qdev.blocksize) {
1800 memcpy(&buf[i], inbuf, s->qdev.blocksize);
1801 }
1802
1803 scsi_req_ref(&r->req);
1804 block_acct_start(blk_get_stats(s->qdev.conf.blk), &r->acct,
1805 data->iov.iov_len, BLOCK_ACCT_WRITE);
1806 r->req.aiocb = blk_aio_writev(s->qdev.conf.blk, data->sector,
1807 &data->qiov, data->iov.iov_len / 512,
1808 scsi_write_same_complete, data);
1809}
1810
1811static void scsi_disk_emulate_write_data(SCSIRequest *req)
1812{
1813 SCSIDiskReq *r = DO_UPCAST(SCSIDiskReq, req, req);
1814
1815 if (r->iov.iov_len) {
1816 int buflen = r->iov.iov_len;
1817 DPRINTF("Write buf_len=%d\n", buflen);
1818 r->iov.iov_len = 0;
1819 scsi_req_data(&r->req, buflen);
1820 return;
1821 }
1822
1823 switch (req->cmd.buf[0]) {
1824 case MODE_SELECT:
1825 case MODE_SELECT_10:
1826
1827 scsi_disk_emulate_mode_select(r, r->iov.iov_base);
1828 break;
1829
1830 case UNMAP:
1831 scsi_disk_emulate_unmap(r, r->iov.iov_base);
1832 break;
1833
1834 case VERIFY_10:
1835 case VERIFY_12:
1836 case VERIFY_16:
1837 if (r->req.status == -1) {
1838 scsi_check_condition(r, SENSE_CODE(INVALID_FIELD));
1839 }
1840 break;
1841
1842 case WRITE_SAME_10:
1843 case WRITE_SAME_16:
1844 scsi_disk_emulate_write_same(r, r->iov.iov_base);
1845 break;
1846
1847 default:
1848 abort();
1849 }
1850}
1851
1852static int32_t scsi_disk_emulate_command(SCSIRequest *req, uint8_t *buf)
1853{
1854 SCSIDiskReq *r = DO_UPCAST(SCSIDiskReq, req, req);
1855 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev);
1856 uint64_t nb_sectors;
1857 uint8_t *outbuf;
1858 int buflen;
1859
1860 switch (req->cmd.buf[0]) {
1861 case INQUIRY:
1862 case MODE_SENSE:
1863 case MODE_SENSE_10:
1864 case RESERVE:
1865 case RESERVE_10:
1866 case RELEASE:
1867 case RELEASE_10:
1868 case START_STOP:
1869 case ALLOW_MEDIUM_REMOVAL:
1870 case GET_CONFIGURATION:
1871 case GET_EVENT_STATUS_NOTIFICATION:
1872 case MECHANISM_STATUS:
1873 case REQUEST_SENSE:
1874 break;
1875
1876 default:
1877 if (s->tray_open || !blk_is_inserted(s->qdev.conf.blk)) {
1878 scsi_check_condition(r, SENSE_CODE(NO_MEDIUM));
1879 return 0;
1880 }
1881 break;
1882 }
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892 if (req->cmd.xfer > 65536) {
1893 goto illegal_request;
1894 }
1895 r->buflen = MAX(4096, req->cmd.xfer);
1896
1897 if (!r->iov.iov_base) {
1898 r->iov.iov_base = blk_blockalign(s->qdev.conf.blk, r->buflen);
1899 }
1900
1901 buflen = req->cmd.xfer;
1902 outbuf = r->iov.iov_base;
1903 memset(outbuf, 0, r->buflen);
1904 switch (req->cmd.buf[0]) {
1905 case TEST_UNIT_READY:
1906 assert(!s->tray_open && blk_is_inserted(s->qdev.conf.blk));
1907 break;
1908 case INQUIRY:
1909 buflen = scsi_disk_emulate_inquiry(req, outbuf);
1910 if (buflen < 0) {
1911 goto illegal_request;
1912 }
1913 break;
1914 case MODE_SENSE:
1915 case MODE_SENSE_10:
1916 buflen = scsi_disk_emulate_mode_sense(r, outbuf);
1917 if (buflen < 0) {
1918 goto illegal_request;
1919 }
1920 break;
1921 case READ_TOC:
1922 buflen = scsi_disk_emulate_read_toc(req, outbuf);
1923 if (buflen < 0) {
1924 goto illegal_request;
1925 }
1926 break;
1927 case RESERVE:
1928 if (req->cmd.buf[1] & 1) {
1929 goto illegal_request;
1930 }
1931 break;
1932 case RESERVE_10:
1933 if (req->cmd.buf[1] & 3) {
1934 goto illegal_request;
1935 }
1936 break;
1937 case RELEASE:
1938 if (req->cmd.buf[1] & 1) {
1939 goto illegal_request;
1940 }
1941 break;
1942 case RELEASE_10:
1943 if (req->cmd.buf[1] & 3) {
1944 goto illegal_request;
1945 }
1946 break;
1947 case START_STOP:
1948 if (scsi_disk_emulate_start_stop(r) < 0) {
1949 return 0;
1950 }
1951 break;
1952 case ALLOW_MEDIUM_REMOVAL:
1953 s->tray_locked = req->cmd.buf[4] & 1;
1954 blk_lock_medium(s->qdev.conf.blk, req->cmd.buf[4] & 1);
1955 break;
1956 case READ_CAPACITY_10:
1957
1958 memset(outbuf, 0, 8);
1959 blk_get_geometry(s->qdev.conf.blk, &nb_sectors);
1960 if (!nb_sectors) {
1961 scsi_check_condition(r, SENSE_CODE(LUN_NOT_READY));
1962 return 0;
1963 }
1964 if ((req->cmd.buf[8] & 1) == 0 && req->cmd.lba) {
1965 goto illegal_request;
1966 }
1967 nb_sectors /= s->qdev.blocksize / 512;
1968
1969 nb_sectors--;
1970
1971 s->qdev.max_lba = nb_sectors;
1972
1973 if (nb_sectors > UINT32_MAX) {
1974 nb_sectors = UINT32_MAX;
1975 }
1976 outbuf[0] = (nb_sectors >> 24) & 0xff;
1977 outbuf[1] = (nb_sectors >> 16) & 0xff;
1978 outbuf[2] = (nb_sectors >> 8) & 0xff;
1979 outbuf[3] = nb_sectors & 0xff;
1980 outbuf[4] = 0;
1981 outbuf[5] = 0;
1982 outbuf[6] = s->qdev.blocksize >> 8;
1983 outbuf[7] = 0;
1984 break;
1985 case REQUEST_SENSE:
1986
1987 buflen = scsi_build_sense(NULL, 0, outbuf, r->buflen,
1988 (req->cmd.buf[1] & 1) == 0);
1989 if (buflen < 0) {
1990 goto illegal_request;
1991 }
1992 break;
1993 case MECHANISM_STATUS:
1994 buflen = scsi_emulate_mechanism_status(s, outbuf);
1995 if (buflen < 0) {
1996 goto illegal_request;
1997 }
1998 break;
1999 case GET_CONFIGURATION:
2000 buflen = scsi_get_configuration(s, outbuf);
2001 if (buflen < 0) {
2002 goto illegal_request;
2003 }
2004 break;
2005 case GET_EVENT_STATUS_NOTIFICATION:
2006 buflen = scsi_get_event_status_notification(s, r, outbuf);
2007 if (buflen < 0) {
2008 goto illegal_request;
2009 }
2010 break;
2011 case READ_DISC_INFORMATION:
2012 buflen = scsi_read_disc_information(s, r, outbuf);
2013 if (buflen < 0) {
2014 goto illegal_request;
2015 }
2016 break;
2017 case READ_DVD_STRUCTURE:
2018 buflen = scsi_read_dvd_structure(s, r, outbuf);
2019 if (buflen < 0) {
2020 goto illegal_request;
2021 }
2022 break;
2023 case SERVICE_ACTION_IN_16:
2024
2025 if ((req->cmd.buf[1] & 31) == SAI_READ_CAPACITY_16) {
2026 DPRINTF("SAI READ CAPACITY(16)\n");
2027 memset(outbuf, 0, req->cmd.xfer);
2028 blk_get_geometry(s->qdev.conf.blk, &nb_sectors);
2029 if (!nb_sectors) {
2030 scsi_check_condition(r, SENSE_CODE(LUN_NOT_READY));
2031 return 0;
2032 }
2033 if ((req->cmd.buf[14] & 1) == 0 && req->cmd.lba) {
2034 goto illegal_request;
2035 }
2036 nb_sectors /= s->qdev.blocksize / 512;
2037
2038 nb_sectors--;
2039
2040 s->qdev.max_lba = nb_sectors;
2041 outbuf[0] = (nb_sectors >> 56) & 0xff;
2042 outbuf[1] = (nb_sectors >> 48) & 0xff;
2043 outbuf[2] = (nb_sectors >> 40) & 0xff;
2044 outbuf[3] = (nb_sectors >> 32) & 0xff;
2045 outbuf[4] = (nb_sectors >> 24) & 0xff;
2046 outbuf[5] = (nb_sectors >> 16) & 0xff;
2047 outbuf[6] = (nb_sectors >> 8) & 0xff;
2048 outbuf[7] = nb_sectors & 0xff;
2049 outbuf[8] = 0;
2050 outbuf[9] = 0;
2051 outbuf[10] = s->qdev.blocksize >> 8;
2052 outbuf[11] = 0;
2053 outbuf[12] = 0;
2054 outbuf[13] = get_physical_block_exp(&s->qdev.conf);
2055
2056
2057 if (s->qdev.conf.discard_granularity) {
2058 outbuf[14] = 0x80;
2059 }
2060
2061
2062 break;
2063 }
2064 DPRINTF("Unsupported Service Action In\n");
2065 goto illegal_request;
2066 case SYNCHRONIZE_CACHE:
2067
2068 scsi_req_ref(&r->req);
2069 block_acct_start(blk_get_stats(s->qdev.conf.blk), &r->acct, 0,
2070 BLOCK_ACCT_FLUSH);
2071 r->req.aiocb = blk_aio_flush(s->qdev.conf.blk, scsi_aio_complete, r);
2072 return 0;
2073 case SEEK_10:
2074 DPRINTF("Seek(10) (sector %" PRId64 ")\n", r->req.cmd.lba);
2075 if (r->req.cmd.lba > s->qdev.max_lba) {
2076 goto illegal_lba;
2077 }
2078 break;
2079 case MODE_SELECT:
2080 DPRINTF("Mode Select(6) (len %lu)\n", (long)r->req.cmd.xfer);
2081 break;
2082 case MODE_SELECT_10:
2083 DPRINTF("Mode Select(10) (len %lu)\n", (long)r->req.cmd.xfer);
2084 break;
2085 case UNMAP:
2086 DPRINTF("Unmap (len %lu)\n", (long)r->req.cmd.xfer);
2087 break;
2088 case VERIFY_10:
2089 case VERIFY_12:
2090 case VERIFY_16:
2091 DPRINTF("Verify (bytchk %d)\n", (req->cmd.buf[1] >> 1) & 3);
2092 if (req->cmd.buf[1] & 6) {
2093 goto illegal_request;
2094 }
2095 break;
2096 case WRITE_SAME_10:
2097 case WRITE_SAME_16:
2098 DPRINTF("WRITE SAME %d (len %lu)\n",
2099 req->cmd.buf[0] == WRITE_SAME_10 ? 10 : 16,
2100 (long)r->req.cmd.xfer);
2101 break;
2102 default:
2103 DPRINTF("Unknown SCSI command (%2.2x=%s)\n", buf[0],
2104 scsi_command_name(buf[0]));
2105 scsi_check_condition(r, SENSE_CODE(INVALID_OPCODE));
2106 return 0;
2107 }
2108 assert(!r->req.aiocb);
2109 r->iov.iov_len = MIN(r->buflen, req->cmd.xfer);
2110 if (r->iov.iov_len == 0) {
2111 scsi_req_complete(&r->req, GOOD);
2112 }
2113 if (r->req.cmd.mode == SCSI_XFER_TO_DEV) {
2114 assert(r->iov.iov_len == req->cmd.xfer);
2115 return -r->iov.iov_len;
2116 } else {
2117 return r->iov.iov_len;
2118 }
2119
2120illegal_request:
2121 if (r->req.status == -1) {
2122 scsi_check_condition(r, SENSE_CODE(INVALID_FIELD));
2123 }
2124 return 0;
2125
2126illegal_lba:
2127 scsi_check_condition(r, SENSE_CODE(LBA_OUT_OF_RANGE));
2128 return 0;
2129}
2130
2131
2132
2133
2134
2135
2136static int32_t scsi_disk_dma_command(SCSIRequest *req, uint8_t *buf)
2137{
2138 SCSIDiskReq *r = DO_UPCAST(SCSIDiskReq, req, req);
2139 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev);
2140 uint32_t len;
2141 uint8_t command;
2142
2143 command = buf[0];
2144
2145 if (s->tray_open || !blk_is_inserted(s->qdev.conf.blk)) {
2146 scsi_check_condition(r, SENSE_CODE(NO_MEDIUM));
2147 return 0;
2148 }
2149
2150 len = scsi_data_cdb_xfer(r->req.cmd.buf);
2151 switch (command) {
2152 case READ_6:
2153 case READ_10:
2154 case READ_12:
2155 case READ_16:
2156 DPRINTF("Read (sector %" PRId64 ", count %u)\n", r->req.cmd.lba, len);
2157 if (r->req.cmd.buf[1] & 0xe0) {
2158 goto illegal_request;
2159 }
2160 if (!check_lba_range(s, r->req.cmd.lba, len)) {
2161 goto illegal_lba;
2162 }
2163 r->sector = r->req.cmd.lba * (s->qdev.blocksize / 512);
2164 r->sector_count = len * (s->qdev.blocksize / 512);
2165 break;
2166 case WRITE_6:
2167 case WRITE_10:
2168 case WRITE_12:
2169 case WRITE_16:
2170 case WRITE_VERIFY_10:
2171 case WRITE_VERIFY_12:
2172 case WRITE_VERIFY_16:
2173 if (blk_is_read_only(s->qdev.conf.blk)) {
2174 scsi_check_condition(r, SENSE_CODE(WRITE_PROTECTED));
2175 return 0;
2176 }
2177 DPRINTF("Write %s(sector %" PRId64 ", count %u)\n",
2178 (command & 0xe) == 0xe ? "And Verify " : "",
2179 r->req.cmd.lba, len);
2180 if (r->req.cmd.buf[1] & 0xe0) {
2181 goto illegal_request;
2182 }
2183 if (!check_lba_range(s, r->req.cmd.lba, len)) {
2184 goto illegal_lba;
2185 }
2186 r->sector = r->req.cmd.lba * (s->qdev.blocksize / 512);
2187 r->sector_count = len * (s->qdev.blocksize / 512);
2188 break;
2189 default:
2190 abort();
2191 illegal_request:
2192 scsi_check_condition(r, SENSE_CODE(INVALID_FIELD));
2193 return 0;
2194 illegal_lba:
2195 scsi_check_condition(r, SENSE_CODE(LBA_OUT_OF_RANGE));
2196 return 0;
2197 }
2198 if (r->sector_count == 0) {
2199 scsi_req_complete(&r->req, GOOD);
2200 }
2201 assert(r->iov.iov_len == 0);
2202 if (r->req.cmd.mode == SCSI_XFER_TO_DEV) {
2203 return -r->sector_count * 512;
2204 } else {
2205 return r->sector_count * 512;
2206 }
2207}
2208
2209static void scsi_disk_reset(DeviceState *dev)
2210{
2211 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev.qdev, dev);
2212 uint64_t nb_sectors;
2213
2214 scsi_device_purge_requests(&s->qdev, SENSE_CODE(RESET));
2215
2216 blk_get_geometry(s->qdev.conf.blk, &nb_sectors);
2217 nb_sectors /= s->qdev.blocksize / 512;
2218 if (nb_sectors) {
2219 nb_sectors--;
2220 }
2221 s->qdev.max_lba = nb_sectors;
2222
2223 s->tray_locked = 0;
2224 s->tray_open = 0;
2225}
2226
2227static void scsi_disk_resize_cb(void *opaque)
2228{
2229 SCSIDiskState *s = opaque;
2230
2231
2232
2233
2234 if (s->qdev.type == TYPE_DISK) {
2235 scsi_device_report_change(&s->qdev, SENSE_CODE(CAPACITY_CHANGED));
2236 }
2237}
2238
2239static void scsi_cd_change_media_cb(void *opaque, bool load)
2240{
2241 SCSIDiskState *s = opaque;
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253 s->media_changed = load;
2254 s->tray_open = !load;
2255 scsi_device_set_ua(&s->qdev, SENSE_CODE(UNIT_ATTENTION_NO_MEDIUM));
2256 s->media_event = true;
2257 s->eject_request = false;
2258}
2259
2260static void scsi_cd_eject_request_cb(void *opaque, bool force)
2261{
2262 SCSIDiskState *s = opaque;
2263
2264 s->eject_request = true;
2265 if (force) {
2266 s->tray_locked = false;
2267 }
2268}
2269
2270static bool scsi_cd_is_tray_open(void *opaque)
2271{
2272 return ((SCSIDiskState *)opaque)->tray_open;
2273}
2274
2275static bool scsi_cd_is_medium_locked(void *opaque)
2276{
2277 return ((SCSIDiskState *)opaque)->tray_locked;
2278}
2279
2280static const BlockDevOps scsi_disk_removable_block_ops = {
2281 .change_media_cb = scsi_cd_change_media_cb,
2282 .eject_request_cb = scsi_cd_eject_request_cb,
2283 .is_tray_open = scsi_cd_is_tray_open,
2284 .is_medium_locked = scsi_cd_is_medium_locked,
2285
2286 .resize_cb = scsi_disk_resize_cb,
2287};
2288
2289static const BlockDevOps scsi_disk_block_ops = {
2290 .resize_cb = scsi_disk_resize_cb,
2291};
2292
2293static void scsi_disk_unit_attention_reported(SCSIDevice *dev)
2294{
2295 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
2296 if (s->media_changed) {
2297 s->media_changed = false;
2298 scsi_device_set_ua(&s->qdev, SENSE_CODE(MEDIUM_CHANGED));
2299 }
2300}
2301
2302static void scsi_realize(SCSIDevice *dev, Error **errp)
2303{
2304 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
2305 Error *err = NULL;
2306
2307 if (!s->qdev.conf.blk) {
2308 error_setg(errp, "drive property not set");
2309 return;
2310 }
2311
2312 if (!(s->features & (1 << SCSI_DISK_F_REMOVABLE)) &&
2313 !blk_is_inserted(s->qdev.conf.blk)) {
2314 error_setg(errp, "Device needs media, but drive is empty");
2315 return;
2316 }
2317
2318 blkconf_serial(&s->qdev.conf, &s->serial);
2319 blkconf_blocksizes(&s->qdev.conf);
2320 if (dev->type == TYPE_DISK) {
2321 blkconf_geometry(&dev->conf, NULL, 65535, 255, 255, &err);
2322 if (err) {
2323 error_propagate(errp, err);
2324 return;
2325 }
2326 }
2327
2328 if (s->qdev.conf.discard_granularity == -1) {
2329 s->qdev.conf.discard_granularity =
2330 MAX(s->qdev.conf.logical_block_size, DEFAULT_DISCARD_GRANULARITY);
2331 }
2332
2333 if (!s->version) {
2334 s->version = g_strdup(qemu_hw_version());
2335 }
2336 if (!s->vendor) {
2337 s->vendor = g_strdup("QEMU");
2338 }
2339
2340 if (blk_is_sg(s->qdev.conf.blk)) {
2341 error_setg(errp, "unwanted /dev/sg*");
2342 return;
2343 }
2344
2345 if ((s->features & (1 << SCSI_DISK_F_REMOVABLE)) &&
2346 !(s->features & (1 << SCSI_DISK_F_NO_REMOVABLE_DEVOPS))) {
2347 blk_set_dev_ops(s->qdev.conf.blk, &scsi_disk_removable_block_ops, s);
2348 } else {
2349 blk_set_dev_ops(s->qdev.conf.blk, &scsi_disk_block_ops, s);
2350 }
2351 blk_set_guest_block_size(s->qdev.conf.blk, s->qdev.blocksize);
2352
2353 blk_iostatus_enable(s->qdev.conf.blk);
2354}
2355
2356static void scsi_hd_realize(SCSIDevice *dev, Error **errp)
2357{
2358 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
2359
2360
2361
2362 if (s->qdev.conf.blk) {
2363 blkconf_blocksizes(&s->qdev.conf);
2364 }
2365 s->qdev.blocksize = s->qdev.conf.logical_block_size;
2366 s->qdev.type = TYPE_DISK;
2367 if (!s->product) {
2368 s->product = g_strdup("QEMU HARDDISK");
2369 }
2370 scsi_realize(&s->qdev, errp);
2371}
2372
2373static void scsi_cd_realize(SCSIDevice *dev, Error **errp)
2374{
2375 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
2376 s->qdev.blocksize = 2048;
2377 s->qdev.type = TYPE_ROM;
2378 s->features |= 1 << SCSI_DISK_F_REMOVABLE;
2379 if (!s->product) {
2380 s->product = g_strdup("QEMU CD-ROM");
2381 }
2382 scsi_realize(&s->qdev, errp);
2383}
2384
2385static void scsi_disk_realize(SCSIDevice *dev, Error **errp)
2386{
2387 DriveInfo *dinfo;
2388 Error *local_err = NULL;
2389
2390 if (!dev->conf.blk) {
2391 scsi_realize(dev, &local_err);
2392 assert(local_err);
2393 error_propagate(errp, local_err);
2394 return;
2395 }
2396
2397 dinfo = blk_legacy_dinfo(dev->conf.blk);
2398 if (dinfo && dinfo->media_cd) {
2399 scsi_cd_realize(dev, errp);
2400 } else {
2401 scsi_hd_realize(dev, errp);
2402 }
2403}
2404
2405static const SCSIReqOps scsi_disk_emulate_reqops = {
2406 .size = sizeof(SCSIDiskReq),
2407 .free_req = scsi_free_request,
2408 .send_command = scsi_disk_emulate_command,
2409 .read_data = scsi_disk_emulate_read_data,
2410 .write_data = scsi_disk_emulate_write_data,
2411 .get_buf = scsi_get_buf,
2412};
2413
2414static const SCSIReqOps scsi_disk_dma_reqops = {
2415 .size = sizeof(SCSIDiskReq),
2416 .free_req = scsi_free_request,
2417 .send_command = scsi_disk_dma_command,
2418 .read_data = scsi_read_data,
2419 .write_data = scsi_write_data,
2420 .get_buf = scsi_get_buf,
2421 .load_request = scsi_disk_load_request,
2422 .save_request = scsi_disk_save_request,
2423};
2424
2425static const SCSIReqOps *const scsi_disk_reqops_dispatch[256] = {
2426 [TEST_UNIT_READY] = &scsi_disk_emulate_reqops,
2427 [INQUIRY] = &scsi_disk_emulate_reqops,
2428 [MODE_SENSE] = &scsi_disk_emulate_reqops,
2429 [MODE_SENSE_10] = &scsi_disk_emulate_reqops,
2430 [START_STOP] = &scsi_disk_emulate_reqops,
2431 [ALLOW_MEDIUM_REMOVAL] = &scsi_disk_emulate_reqops,
2432 [READ_CAPACITY_10] = &scsi_disk_emulate_reqops,
2433 [READ_TOC] = &scsi_disk_emulate_reqops,
2434 [READ_DVD_STRUCTURE] = &scsi_disk_emulate_reqops,
2435 [READ_DISC_INFORMATION] = &scsi_disk_emulate_reqops,
2436 [GET_CONFIGURATION] = &scsi_disk_emulate_reqops,
2437 [GET_EVENT_STATUS_NOTIFICATION] = &scsi_disk_emulate_reqops,
2438 [MECHANISM_STATUS] = &scsi_disk_emulate_reqops,
2439 [SERVICE_ACTION_IN_16] = &scsi_disk_emulate_reqops,
2440 [REQUEST_SENSE] = &scsi_disk_emulate_reqops,
2441 [SYNCHRONIZE_CACHE] = &scsi_disk_emulate_reqops,
2442 [SEEK_10] = &scsi_disk_emulate_reqops,
2443 [MODE_SELECT] = &scsi_disk_emulate_reqops,
2444 [MODE_SELECT_10] = &scsi_disk_emulate_reqops,
2445 [UNMAP] = &scsi_disk_emulate_reqops,
2446 [WRITE_SAME_10] = &scsi_disk_emulate_reqops,
2447 [WRITE_SAME_16] = &scsi_disk_emulate_reqops,
2448 [VERIFY_10] = &scsi_disk_emulate_reqops,
2449 [VERIFY_12] = &scsi_disk_emulate_reqops,
2450 [VERIFY_16] = &scsi_disk_emulate_reqops,
2451
2452 [READ_6] = &scsi_disk_dma_reqops,
2453 [READ_10] = &scsi_disk_dma_reqops,
2454 [READ_12] = &scsi_disk_dma_reqops,
2455 [READ_16] = &scsi_disk_dma_reqops,
2456 [WRITE_6] = &scsi_disk_dma_reqops,
2457 [WRITE_10] = &scsi_disk_dma_reqops,
2458 [WRITE_12] = &scsi_disk_dma_reqops,
2459 [WRITE_16] = &scsi_disk_dma_reqops,
2460 [WRITE_VERIFY_10] = &scsi_disk_dma_reqops,
2461 [WRITE_VERIFY_12] = &scsi_disk_dma_reqops,
2462 [WRITE_VERIFY_16] = &scsi_disk_dma_reqops,
2463};
2464
2465static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun,
2466 uint8_t *buf, void *hba_private)
2467{
2468 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, d);
2469 SCSIRequest *req;
2470 const SCSIReqOps *ops;
2471 uint8_t command;
2472
2473 command = buf[0];
2474 ops = scsi_disk_reqops_dispatch[command];
2475 if (!ops) {
2476 ops = &scsi_disk_emulate_reqops;
2477 }
2478 req = scsi_req_alloc(ops, &s->qdev, tag, lun, hba_private);
2479
2480#ifdef DEBUG_SCSI
2481 DPRINTF("Command: lun=%d tag=0x%x data=0x%02x", lun, tag, buf[0]);
2482 {
2483 int i;
2484 for (i = 1; i < scsi_cdb_length(buf); i++) {
2485 printf(" 0x%02x", buf[i]);
2486 }
2487 printf("\n");
2488 }
2489#endif
2490
2491 return req;
2492}
2493
2494#ifdef __linux__
2495static int get_device_type(SCSIDiskState *s)
2496{
2497 uint8_t cmd[16];
2498 uint8_t buf[36];
2499 uint8_t sensebuf[8];
2500 sg_io_hdr_t io_header;
2501 int ret;
2502
2503 memset(cmd, 0, sizeof(cmd));
2504 memset(buf, 0, sizeof(buf));
2505 cmd[0] = INQUIRY;
2506 cmd[4] = sizeof(buf);
2507
2508 memset(&io_header, 0, sizeof(io_header));
2509 io_header.interface_id = 'S';
2510 io_header.dxfer_direction = SG_DXFER_FROM_DEV;
2511 io_header.dxfer_len = sizeof(buf);
2512 io_header.dxferp = buf;
2513 io_header.cmdp = cmd;
2514 io_header.cmd_len = sizeof(cmd);
2515 io_header.mx_sb_len = sizeof(sensebuf);
2516 io_header.sbp = sensebuf;
2517 io_header.timeout = 6000;
2518
2519 ret = blk_ioctl(s->qdev.conf.blk, SG_IO, &io_header);
2520 if (ret < 0 || io_header.driver_status || io_header.host_status) {
2521 return -1;
2522 }
2523 s->qdev.type = buf[0];
2524 if (buf[1] & 0x80) {
2525 s->features |= 1 << SCSI_DISK_F_REMOVABLE;
2526 }
2527 return 0;
2528}
2529
2530static void scsi_block_realize(SCSIDevice *dev, Error **errp)
2531{
2532 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
2533 int sg_version;
2534 int rc;
2535
2536 if (!s->qdev.conf.blk) {
2537 error_setg(errp, "drive property not set");
2538 return;
2539 }
2540
2541
2542 rc = blk_ioctl(s->qdev.conf.blk, SG_GET_VERSION_NUM, &sg_version);
2543 if (rc < 0) {
2544 error_setg(errp, "cannot get SG_IO version number: %s. "
2545 "Is this a SCSI device?",
2546 strerror(-rc));
2547 return;
2548 }
2549 if (sg_version < 30000) {
2550 error_setg(errp, "scsi generic interface too old");
2551 return;
2552 }
2553
2554
2555 rc = get_device_type(s);
2556 if (rc < 0) {
2557 error_setg(errp, "INQUIRY failed");
2558 return;
2559 }
2560
2561
2562
2563
2564
2565 if (s->qdev.type == TYPE_ROM || s->qdev.type == TYPE_WORM) {
2566 s->qdev.blocksize = 2048;
2567 } else {
2568 s->qdev.blocksize = 512;
2569 }
2570
2571
2572
2573
2574 s->features |= (1 << SCSI_DISK_F_NO_REMOVABLE_DEVOPS);
2575
2576 scsi_realize(&s->qdev, errp);
2577 scsi_generic_read_device_identification(&s->qdev);
2578}
2579
2580static bool scsi_block_is_passthrough(SCSIDiskState *s, uint8_t *buf)
2581{
2582 switch (buf[0]) {
2583 case READ_6:
2584 case READ_10:
2585 case READ_12:
2586 case READ_16:
2587 case VERIFY_10:
2588 case VERIFY_12:
2589 case VERIFY_16:
2590 case WRITE_6:
2591 case WRITE_10:
2592 case WRITE_12:
2593 case WRITE_16:
2594 case WRITE_VERIFY_10:
2595 case WRITE_VERIFY_12:
2596 case WRITE_VERIFY_16:
2597
2598
2599
2600
2601
2602 if (!(blk_get_flags(s->qdev.conf.blk) & BDRV_O_NOCACHE)) {
2603 break;
2604 }
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616 if (s->qdev.type != TYPE_ROM) {
2617 return false;
2618 }
2619 break;
2620
2621 default:
2622 break;
2623 }
2624
2625 return true;
2626}
2627
2628
2629static SCSIRequest *scsi_block_new_request(SCSIDevice *d, uint32_t tag,
2630 uint32_t lun, uint8_t *buf,
2631 void *hba_private)
2632{
2633 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, d);
2634
2635 if (scsi_block_is_passthrough(s, buf)) {
2636 return scsi_req_alloc(&scsi_generic_req_ops, &s->qdev, tag, lun,
2637 hba_private);
2638 } else {
2639 return scsi_req_alloc(&scsi_disk_dma_reqops, &s->qdev, tag, lun,
2640 hba_private);
2641 }
2642}
2643
2644static int scsi_block_parse_cdb(SCSIDevice *d, SCSICommand *cmd,
2645 uint8_t *buf, void *hba_private)
2646{
2647 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, d);
2648
2649 if (scsi_block_is_passthrough(s, buf)) {
2650 return scsi_bus_parse_cdb(&s->qdev, cmd, buf, hba_private);
2651 } else {
2652 return scsi_req_parse_cdb(&s->qdev, cmd, buf);
2653 }
2654}
2655
2656#endif
2657
2658#define DEFINE_SCSI_DISK_PROPERTIES() \
2659 DEFINE_BLOCK_PROPERTIES(SCSIDiskState, qdev.conf), \
2660 DEFINE_PROP_STRING("ver", SCSIDiskState, version), \
2661 DEFINE_PROP_STRING("serial", SCSIDiskState, serial), \
2662 DEFINE_PROP_STRING("vendor", SCSIDiskState, vendor), \
2663 DEFINE_PROP_STRING("product", SCSIDiskState, product)
2664
2665static Property scsi_hd_properties[] = {
2666 DEFINE_SCSI_DISK_PROPERTIES(),
2667 DEFINE_PROP_BIT("removable", SCSIDiskState, features,
2668 SCSI_DISK_F_REMOVABLE, false),
2669 DEFINE_PROP_BIT("dpofua", SCSIDiskState, features,
2670 SCSI_DISK_F_DPOFUA, false),
2671 DEFINE_PROP_UINT64("wwn", SCSIDiskState, qdev.wwn, 0),
2672 DEFINE_PROP_UINT64("port_wwn", SCSIDiskState, qdev.port_wwn, 0),
2673 DEFINE_PROP_UINT16("port_index", SCSIDiskState, port_index, 0),
2674 DEFINE_PROP_UINT64("max_unmap_size", SCSIDiskState, max_unmap_size,
2675 DEFAULT_MAX_UNMAP_SIZE),
2676 DEFINE_PROP_UINT64("max_io_size", SCSIDiskState, max_io_size,
2677 DEFAULT_MAX_IO_SIZE),
2678 DEFINE_BLOCK_CHS_PROPERTIES(SCSIDiskState, qdev.conf),
2679 DEFINE_PROP_END_OF_LIST(),
2680};
2681
2682static const VMStateDescription vmstate_scsi_disk_state = {
2683 .name = "scsi-disk",
2684 .version_id = 1,
2685 .minimum_version_id = 1,
2686 .fields = (VMStateField[]) {
2687 VMSTATE_SCSI_DEVICE(qdev, SCSIDiskState),
2688 VMSTATE_BOOL(media_changed, SCSIDiskState),
2689 VMSTATE_BOOL(media_event, SCSIDiskState),
2690 VMSTATE_BOOL(eject_request, SCSIDiskState),
2691 VMSTATE_BOOL(tray_open, SCSIDiskState),
2692 VMSTATE_BOOL(tray_locked, SCSIDiskState),
2693 VMSTATE_END_OF_LIST()
2694 }
2695};
2696
2697static void scsi_hd_class_initfn(ObjectClass *klass, void *data)
2698{
2699 DeviceClass *dc = DEVICE_CLASS(klass);
2700 SCSIDeviceClass *sc = SCSI_DEVICE_CLASS(klass);
2701
2702 sc->realize = scsi_hd_realize;
2703 sc->alloc_req = scsi_new_request;
2704 sc->unit_attention_reported = scsi_disk_unit_attention_reported;
2705 dc->fw_name = "disk";
2706 dc->desc = "virtual SCSI disk";
2707 dc->reset = scsi_disk_reset;
2708 dc->props = scsi_hd_properties;
2709 dc->vmsd = &vmstate_scsi_disk_state;
2710}
2711
2712static const TypeInfo scsi_hd_info = {
2713 .name = "scsi-hd",
2714 .parent = TYPE_SCSI_DEVICE,
2715 .instance_size = sizeof(SCSIDiskState),
2716 .class_init = scsi_hd_class_initfn,
2717};
2718
2719static Property scsi_cd_properties[] = {
2720 DEFINE_SCSI_DISK_PROPERTIES(),
2721 DEFINE_PROP_UINT64("wwn", SCSIDiskState, qdev.wwn, 0),
2722 DEFINE_PROP_UINT64("port_wwn", SCSIDiskState, qdev.port_wwn, 0),
2723 DEFINE_PROP_UINT16("port_index", SCSIDiskState, port_index, 0),
2724 DEFINE_PROP_UINT64("max_io_size", SCSIDiskState, max_io_size,
2725 DEFAULT_MAX_IO_SIZE),
2726 DEFINE_PROP_END_OF_LIST(),
2727};
2728
2729static void scsi_cd_class_initfn(ObjectClass *klass, void *data)
2730{
2731 DeviceClass *dc = DEVICE_CLASS(klass);
2732 SCSIDeviceClass *sc = SCSI_DEVICE_CLASS(klass);
2733
2734 sc->realize = scsi_cd_realize;
2735 sc->alloc_req = scsi_new_request;
2736 sc->unit_attention_reported = scsi_disk_unit_attention_reported;
2737 dc->fw_name = "disk";
2738 dc->desc = "virtual SCSI CD-ROM";
2739 dc->reset = scsi_disk_reset;
2740 dc->props = scsi_cd_properties;
2741 dc->vmsd = &vmstate_scsi_disk_state;
2742}
2743
2744static const TypeInfo scsi_cd_info = {
2745 .name = "scsi-cd",
2746 .parent = TYPE_SCSI_DEVICE,
2747 .instance_size = sizeof(SCSIDiskState),
2748 .class_init = scsi_cd_class_initfn,
2749};
2750
2751#ifdef __linux__
2752static Property scsi_block_properties[] = {
2753 DEFINE_PROP_DRIVE("drive", SCSIDiskState, qdev.conf.blk),
2754 DEFINE_PROP_END_OF_LIST(),
2755};
2756
2757static void scsi_block_class_initfn(ObjectClass *klass, void *data)
2758{
2759 DeviceClass *dc = DEVICE_CLASS(klass);
2760 SCSIDeviceClass *sc = SCSI_DEVICE_CLASS(klass);
2761
2762 sc->realize = scsi_block_realize;
2763 sc->alloc_req = scsi_block_new_request;
2764 sc->parse_cdb = scsi_block_parse_cdb;
2765 dc->fw_name = "disk";
2766 dc->desc = "SCSI block device passthrough";
2767 dc->reset = scsi_disk_reset;
2768 dc->props = scsi_block_properties;
2769 dc->vmsd = &vmstate_scsi_disk_state;
2770}
2771
2772static const TypeInfo scsi_block_info = {
2773 .name = "scsi-block",
2774 .parent = TYPE_SCSI_DEVICE,
2775 .instance_size = sizeof(SCSIDiskState),
2776 .class_init = scsi_block_class_initfn,
2777};
2778#endif
2779
2780static Property scsi_disk_properties[] = {
2781 DEFINE_SCSI_DISK_PROPERTIES(),
2782 DEFINE_PROP_BIT("removable", SCSIDiskState, features,
2783 SCSI_DISK_F_REMOVABLE, false),
2784 DEFINE_PROP_BIT("dpofua", SCSIDiskState, features,
2785 SCSI_DISK_F_DPOFUA, false),
2786 DEFINE_PROP_UINT64("wwn", SCSIDiskState, qdev.wwn, 0),
2787 DEFINE_PROP_UINT64("port_wwn", SCSIDiskState, qdev.port_wwn, 0),
2788 DEFINE_PROP_UINT16("port_index", SCSIDiskState, port_index, 0),
2789 DEFINE_PROP_UINT64("max_unmap_size", SCSIDiskState, max_unmap_size,
2790 DEFAULT_MAX_UNMAP_SIZE),
2791 DEFINE_PROP_UINT64("max_io_size", SCSIDiskState, max_io_size,
2792 DEFAULT_MAX_IO_SIZE),
2793 DEFINE_PROP_END_OF_LIST(),
2794};
2795
2796static void scsi_disk_class_initfn(ObjectClass *klass, void *data)
2797{
2798 DeviceClass *dc = DEVICE_CLASS(klass);
2799 SCSIDeviceClass *sc = SCSI_DEVICE_CLASS(klass);
2800
2801 sc->realize = scsi_disk_realize;
2802 sc->alloc_req = scsi_new_request;
2803 sc->unit_attention_reported = scsi_disk_unit_attention_reported;
2804 dc->fw_name = "disk";
2805 dc->desc = "virtual SCSI disk or CD-ROM (legacy)";
2806 dc->reset = scsi_disk_reset;
2807 dc->props = scsi_disk_properties;
2808 dc->vmsd = &vmstate_scsi_disk_state;
2809}
2810
2811static const TypeInfo scsi_disk_info = {
2812 .name = "scsi-disk",
2813 .parent = TYPE_SCSI_DEVICE,
2814 .instance_size = sizeof(SCSIDiskState),
2815 .class_init = scsi_disk_class_initfn,
2816};
2817
2818static void scsi_disk_register_types(void)
2819{
2820 type_register_static(&scsi_hd_info);
2821 type_register_static(&scsi_cd_info);
2822#ifdef __linux__
2823 type_register_static(&scsi_block_info);
2824#endif
2825 type_register_static(&scsi_disk_info);
2826}
2827
2828type_init(scsi_disk_register_types)
2829