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