target-arm: fix strexd
[qemu/aliguori-queue.git] / hw / scsi-disk.c
blobeb5b5a84777fe2accc776bf0de39f71c9341affa
1 /*
2 * SCSI Device emulation
4 * Copyright (c) 2006 CodeSourcery.
5 * Based on code by Fabrice Bellard
7 * Written by Paul Brook
8 * Modifications:
9 * 2009-Dec-12 Artyom Tarasenko : implemented stamdard inquiry for the case
10 * when the allocation length of CDB is smaller
11 * than 36.
12 * 2009-Oct-13 Artyom Tarasenko : implemented the block descriptor in the
13 * MODE SENSE response.
15 * This code is licenced under the LGPL.
17 * Note that this file only handles the SCSI architecture model and device
18 * commands. Emulation of interface/link layer protocols is handled by
19 * the host adapter emulator.
22 #include <qemu-common.h>
23 #include <sysemu.h>
24 //#define DEBUG_SCSI
26 #ifdef DEBUG_SCSI
27 #define DPRINTF(fmt, ...) \
28 do { printf("scsi-disk: " fmt , ## __VA_ARGS__); } while (0)
29 #else
30 #define DPRINTF(fmt, ...) do {} while(0)
31 #endif
33 #define BADF(fmt, ...) \
34 do { fprintf(stderr, "scsi-disk: " fmt , ## __VA_ARGS__); } while (0)
36 #include "qemu-common.h"
37 #include "block.h"
38 #include "scsi.h"
39 #include "scsi-defs.h"
41 #define SCSI_DMA_BUF_SIZE 131072
42 #define SCSI_MAX_INQUIRY_LEN 256
44 #define SCSI_REQ_STATUS_RETRY 0x01
46 typedef struct SCSIDiskState SCSIDiskState;
48 typedef struct SCSIDiskReq {
49 SCSIRequest req;
50 /* ??? We should probably keep track of whether the data transfer is
51 a read or a write. Currently we rely on the host getting it right. */
52 /* Both sector and sector_count are in terms of qemu 512 byte blocks. */
53 uint64_t sector;
54 uint32_t sector_count;
55 struct iovec iov;
56 QEMUIOVector qiov;
57 uint32_t status;
58 } SCSIDiskReq;
60 struct SCSIDiskState
62 SCSIDevice qdev;
63 /* The qemu block layer uses a fixed 512 byte sector size.
64 This is the number of 512 byte blocks in a single scsi sector. */
65 int cluster_size;
66 uint64_t max_lba;
67 QEMUBH *bh;
70 static SCSIDiskReq *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun)
72 SCSIRequest *req;
73 SCSIDiskReq *r;
75 req = scsi_req_alloc(sizeof(SCSIDiskReq), d, tag, lun);
76 r = DO_UPCAST(SCSIDiskReq, req, req);
77 r->iov.iov_base = qemu_memalign(512, SCSI_DMA_BUF_SIZE);
78 return r;
81 static void scsi_remove_request(SCSIDiskReq *r)
83 qemu_free(r->iov.iov_base);
84 scsi_req_free(&r->req);
87 static SCSIDiskReq *scsi_find_request(SCSIDiskState *s, uint32_t tag)
89 return DO_UPCAST(SCSIDiskReq, req, scsi_req_find(&s->qdev, tag));
92 static void scsi_req_set_status(SCSIRequest *req, int status, int sense_code)
94 req->status = status;
95 scsi_dev_set_sense(req->dev, sense_code);
98 /* Helper function for command completion. */
99 static void scsi_command_complete(SCSIDiskReq *r, int status, int sense)
101 DPRINTF("Command complete tag=0x%x status=%d sense=%d\n",
102 r->req.tag, status, sense);
103 scsi_req_set_status(&r->req, status, sense);
104 scsi_req_complete(&r->req);
105 scsi_remove_request(r);
108 /* Cancel a pending data transfer. */
109 static void scsi_cancel_io(SCSIDevice *d, uint32_t tag)
111 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, d);
112 SCSIDiskReq *r;
113 DPRINTF("Cancel tag=0x%x\n", tag);
114 r = scsi_find_request(s, tag);
115 if (r) {
116 if (r->req.aiocb)
117 bdrv_aio_cancel(r->req.aiocb);
118 r->req.aiocb = NULL;
119 scsi_remove_request(r);
123 static void scsi_read_complete(void * opaque, int ret)
125 SCSIDiskReq *r = (SCSIDiskReq *)opaque;
127 if (ret) {
128 DPRINTF("IO error\n");
129 r->req.bus->complete(r->req.bus, SCSI_REASON_DATA, r->req.tag, 0);
130 scsi_command_complete(r, CHECK_CONDITION, NO_SENSE);
131 return;
133 DPRINTF("Data ready tag=0x%x len=%" PRId64 "\n", r->req.tag, r->iov.iov_len);
135 r->req.bus->complete(r->req.bus, SCSI_REASON_DATA, r->req.tag, r->iov.iov_len);
138 /* Read more data from scsi device into buffer. */
139 static void scsi_read_data(SCSIDevice *d, uint32_t tag)
141 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, d);
142 SCSIDiskReq *r;
143 uint32_t n;
145 r = scsi_find_request(s, tag);
146 if (!r) {
147 BADF("Bad read tag 0x%x\n", tag);
148 /* ??? This is the wrong error. */
149 scsi_command_complete(r, CHECK_CONDITION, HARDWARE_ERROR);
150 return;
152 if (r->sector_count == (uint32_t)-1) {
153 DPRINTF("Read buf_len=%" PRId64 "\n", r->iov.iov_len);
154 r->sector_count = 0;
155 r->req.bus->complete(r->req.bus, SCSI_REASON_DATA, r->req.tag, r->iov.iov_len);
156 return;
158 DPRINTF("Read sector_count=%d\n", r->sector_count);
159 if (r->sector_count == 0) {
160 scsi_command_complete(r, GOOD, NO_SENSE);
161 return;
164 n = r->sector_count;
165 if (n > SCSI_DMA_BUF_SIZE / 512)
166 n = SCSI_DMA_BUF_SIZE / 512;
168 r->iov.iov_len = n * 512;
169 qemu_iovec_init_external(&r->qiov, &r->iov, 1);
170 r->req.aiocb = bdrv_aio_readv(s->qdev.dinfo->bdrv, r->sector, &r->qiov, n,
171 scsi_read_complete, r);
172 if (r->req.aiocb == NULL)
173 scsi_command_complete(r, CHECK_CONDITION, HARDWARE_ERROR);
174 r->sector += n;
175 r->sector_count -= n;
178 static int scsi_handle_write_error(SCSIDiskReq *r, int error)
180 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
181 BlockInterfaceErrorAction action =
182 drive_get_on_error(s->qdev.dinfo->bdrv, 0);
184 if (action == BLOCK_ERR_IGNORE)
185 return 0;
187 if ((error == ENOSPC && action == BLOCK_ERR_STOP_ENOSPC)
188 || action == BLOCK_ERR_STOP_ANY) {
189 r->status |= SCSI_REQ_STATUS_RETRY;
190 vm_stop(0);
191 } else {
192 scsi_command_complete(r, CHECK_CONDITION,
193 HARDWARE_ERROR);
196 return 1;
199 static void scsi_write_complete(void * opaque, int ret)
201 SCSIDiskReq *r = (SCSIDiskReq *)opaque;
202 uint32_t len;
203 uint32_t n;
205 r->req.aiocb = NULL;
207 if (ret) {
208 if (scsi_handle_write_error(r, -ret))
209 return;
212 n = r->iov.iov_len / 512;
213 r->sector += n;
214 r->sector_count -= n;
215 if (r->sector_count == 0) {
216 scsi_command_complete(r, GOOD, NO_SENSE);
217 } else {
218 len = r->sector_count * 512;
219 if (len > SCSI_DMA_BUF_SIZE) {
220 len = SCSI_DMA_BUF_SIZE;
222 r->iov.iov_len = len;
223 DPRINTF("Write complete tag=0x%x more=%d\n", r->req.tag, len);
224 r->req.bus->complete(r->req.bus, SCSI_REASON_DATA, r->req.tag, len);
228 static void scsi_write_request(SCSIDiskReq *r)
230 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
231 uint32_t n;
233 n = r->iov.iov_len / 512;
234 if (n) {
235 qemu_iovec_init_external(&r->qiov, &r->iov, 1);
236 r->req.aiocb = bdrv_aio_writev(s->qdev.dinfo->bdrv, r->sector, &r->qiov, n,
237 scsi_write_complete, r);
238 if (r->req.aiocb == NULL)
239 scsi_command_complete(r, CHECK_CONDITION,
240 HARDWARE_ERROR);
241 } else {
242 /* Invoke completion routine to fetch data from host. */
243 scsi_write_complete(r, 0);
247 /* Write data to a scsi device. Returns nonzero on failure.
248 The transfer may complete asynchronously. */
249 static int scsi_write_data(SCSIDevice *d, uint32_t tag)
251 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, d);
252 SCSIDiskReq *r;
254 DPRINTF("Write data tag=0x%x\n", tag);
255 r = scsi_find_request(s, tag);
256 if (!r) {
257 BADF("Bad write tag 0x%x\n", tag);
258 scsi_command_complete(r, CHECK_CONDITION, HARDWARE_ERROR);
259 return 1;
262 if (r->req.aiocb)
263 BADF("Data transfer already in progress\n");
265 scsi_write_request(r);
267 return 0;
270 static void scsi_dma_restart_bh(void *opaque)
272 SCSIDiskState *s = opaque;
273 SCSIRequest *req;
274 SCSIDiskReq *r;
276 qemu_bh_delete(s->bh);
277 s->bh = NULL;
279 QTAILQ_FOREACH(req, &s->qdev.requests, next) {
280 r = DO_UPCAST(SCSIDiskReq, req, req);
281 if (r->status & SCSI_REQ_STATUS_RETRY) {
282 r->status &= ~SCSI_REQ_STATUS_RETRY;
283 scsi_write_request(r);
288 static void scsi_dma_restart_cb(void *opaque, int running, int reason)
290 SCSIDiskState *s = opaque;
292 if (!running)
293 return;
295 if (!s->bh) {
296 s->bh = qemu_bh_new(scsi_dma_restart_bh, s);
297 qemu_bh_schedule(s->bh);
301 /* Return a pointer to the data buffer. */
302 static uint8_t *scsi_get_buf(SCSIDevice *d, uint32_t tag)
304 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, d);
305 SCSIDiskReq *r;
307 r = scsi_find_request(s, tag);
308 if (!r) {
309 BADF("Bad buffer tag 0x%x\n", tag);
310 return NULL;
312 return (uint8_t *)r->iov.iov_base;
315 static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf)
317 BlockDriverState *bdrv = req->dev->dinfo->bdrv;
318 int buflen = 0;
320 if (req->cmd.buf[1] & 0x2) {
321 /* Command support data - optional, not implemented */
322 BADF("optional INQUIRY command support request not implemented\n");
323 return -1;
326 if (req->cmd.buf[1] & 0x1) {
327 /* Vital product data */
328 uint8_t page_code = req->cmd.buf[2];
329 if (req->cmd.xfer < 4) {
330 BADF("Error: Inquiry (EVPD[%02X]) buffer size %zd is "
331 "less than 4\n", page_code, req->cmd.xfer);
332 return -1;
335 if (bdrv_get_type_hint(bdrv) == BDRV_TYPE_CDROM) {
336 outbuf[buflen++] = 5;
337 } else {
338 outbuf[buflen++] = 0;
340 outbuf[buflen++] = page_code ; // this page
341 outbuf[buflen++] = 0x00;
343 switch (page_code) {
344 case 0x00: /* Supported page codes, mandatory */
345 DPRINTF("Inquiry EVPD[Supported pages] "
346 "buffer size %zd\n", req->cmd.xfer);
347 outbuf[buflen++] = 3; // number of pages
348 outbuf[buflen++] = 0x00; // list of supported pages (this page)
349 outbuf[buflen++] = 0x80; // unit serial number
350 outbuf[buflen++] = 0x83; // device identification
351 break;
353 case 0x80: /* Device serial number, optional */
355 const char *serial = req->dev->dinfo->serial ?
356 req->dev->dinfo->serial : "0";
357 int l = strlen(serial);
359 if (l > req->cmd.xfer)
360 l = req->cmd.xfer;
361 if (l > 20)
362 l = 20;
364 DPRINTF("Inquiry EVPD[Serial number] "
365 "buffer size %zd\n", req->cmd.xfer);
366 outbuf[buflen++] = l;
367 memcpy(outbuf+buflen, serial, l);
368 buflen += l;
369 break;
372 case 0x83: /* Device identification page, mandatory */
374 int max_len = 255 - 8;
375 int id_len = strlen(bdrv_get_device_name(bdrv));
377 if (id_len > max_len)
378 id_len = max_len;
379 DPRINTF("Inquiry EVPD[Device identification] "
380 "buffer size %zd\n", req->cmd.xfer);
382 outbuf[buflen++] = 3 + id_len;
383 outbuf[buflen++] = 0x2; // ASCII
384 outbuf[buflen++] = 0; // not officially assigned
385 outbuf[buflen++] = 0; // reserved
386 outbuf[buflen++] = id_len; // length of data following
388 memcpy(outbuf+buflen, bdrv_get_device_name(bdrv), id_len);
389 buflen += id_len;
390 break;
392 default:
393 BADF("Error: unsupported Inquiry (EVPD[%02X]) "
394 "buffer size %zd\n", page_code, req->cmd.xfer);
395 return -1;
397 /* done with EVPD */
398 return buflen;
401 /* Standard INQUIRY data */
402 if (req->cmd.buf[2] != 0) {
403 BADF("Error: Inquiry (STANDARD) page or code "
404 "is non-zero [%02X]\n", req->cmd.buf[2]);
405 return -1;
408 /* PAGE CODE == 0 */
409 if (req->cmd.xfer < 5) {
410 BADF("Error: Inquiry (STANDARD) buffer size %zd "
411 "is less than 5\n", req->cmd.xfer);
412 return -1;
415 buflen = req->cmd.xfer;
416 if (buflen > SCSI_MAX_INQUIRY_LEN)
417 buflen = SCSI_MAX_INQUIRY_LEN;
419 memset(outbuf, 0, buflen);
421 if (req->lun || req->cmd.buf[1] >> 5) {
422 outbuf[0] = 0x7f; /* LUN not supported */
423 return buflen;
426 if (bdrv_get_type_hint(bdrv) == BDRV_TYPE_CDROM) {
427 outbuf[0] = 5;
428 outbuf[1] = 0x80;
429 memcpy(&outbuf[16], "QEMU CD-ROM ", 16);
430 } else {
431 outbuf[0] = 0;
432 memcpy(&outbuf[16], "QEMU HARDDISK ", 16);
434 memcpy(&outbuf[8], "QEMU ", 8);
435 memcpy(&outbuf[32], QEMU_VERSION, 4);
436 /* Identify device as SCSI-3 rev 1.
437 Some later commands are also implemented. */
438 outbuf[2] = 3;
439 outbuf[3] = 2; /* Format 2 */
441 if (buflen > 36) {
442 outbuf[4] = buflen - 5; /* Additional Length = (Len - 1) - 4 */
443 } else {
444 /* If the allocation length of CDB is too small,
445 the additional length is not adjusted */
446 outbuf[4] = 36 - 5;
449 /* Sync data transfer and TCQ. */
450 outbuf[7] = 0x10 | (req->bus->tcq ? 0x02 : 0);
451 return buflen;
454 static int mode_sense_page(SCSIRequest *req, int page, uint8_t *p)
456 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev);
457 BlockDriverState *bdrv = req->dev->dinfo->bdrv;
458 int cylinders, heads, secs;
460 switch (page) {
461 case 4: /* Rigid disk device geometry page. */
462 p[0] = 4;
463 p[1] = 0x16;
464 /* if a geometry hint is available, use it */
465 bdrv_get_geometry_hint(bdrv, &cylinders, &heads, &secs);
466 p[2] = (cylinders >> 16) & 0xff;
467 p[3] = (cylinders >> 8) & 0xff;
468 p[4] = cylinders & 0xff;
469 p[5] = heads & 0xff;
470 /* Write precomp start cylinder, disabled */
471 p[6] = (cylinders >> 16) & 0xff;
472 p[7] = (cylinders >> 8) & 0xff;
473 p[8] = cylinders & 0xff;
474 /* Reduced current start cylinder, disabled */
475 p[9] = (cylinders >> 16) & 0xff;
476 p[10] = (cylinders >> 8) & 0xff;
477 p[11] = cylinders & 0xff;
478 /* Device step rate [ns], 200ns */
479 p[12] = 0;
480 p[13] = 200;
481 /* Landing zone cylinder */
482 p[14] = 0xff;
483 p[15] = 0xff;
484 p[16] = 0xff;
485 /* Medium rotation rate [rpm], 5400 rpm */
486 p[20] = (5400 >> 8) & 0xff;
487 p[21] = 5400 & 0xff;
488 return 0x16;
490 case 5: /* Flexible disk device geometry page. */
491 p[0] = 5;
492 p[1] = 0x1e;
493 /* Transfer rate [kbit/s], 5Mbit/s */
494 p[2] = 5000 >> 8;
495 p[3] = 5000 & 0xff;
496 /* if a geometry hint is available, use it */
497 bdrv_get_geometry_hint(bdrv, &cylinders, &heads, &secs);
498 p[4] = heads & 0xff;
499 p[5] = secs & 0xff;
500 p[6] = s->cluster_size * 2;
501 p[8] = (cylinders >> 8) & 0xff;
502 p[9] = cylinders & 0xff;
503 /* Write precomp start cylinder, disabled */
504 p[10] = (cylinders >> 8) & 0xff;
505 p[11] = cylinders & 0xff;
506 /* Reduced current start cylinder, disabled */
507 p[12] = (cylinders >> 8) & 0xff;
508 p[13] = cylinders & 0xff;
509 /* Device step rate [100us], 100us */
510 p[14] = 0;
511 p[15] = 1;
512 /* Device step pulse width [us], 1us */
513 p[16] = 1;
514 /* Device head settle delay [100us], 100us */
515 p[17] = 0;
516 p[18] = 1;
517 /* Motor on delay [0.1s], 0.1s */
518 p[19] = 1;
519 /* Motor off delay [0.1s], 0.1s */
520 p[20] = 1;
521 /* Medium rotation rate [rpm], 5400 rpm */
522 p[28] = (5400 >> 8) & 0xff;
523 p[29] = 5400 & 0xff;
524 return 0x1e;
526 case 8: /* Caching page. */
527 p[0] = 8;
528 p[1] = 0x12;
529 if (bdrv_enable_write_cache(s->qdev.dinfo->bdrv)) {
530 p[2] = 4; /* WCE */
532 return 20;
534 case 0x2a: /* CD Capabilities and Mechanical Status page. */
535 if (bdrv_get_type_hint(bdrv) != BDRV_TYPE_CDROM)
536 return 0;
537 p[0] = 0x2a;
538 p[1] = 0x14;
539 p[2] = 3; // CD-R & CD-RW read
540 p[3] = 0; // Writing not supported
541 p[4] = 0x7f; /* Audio, composite, digital out,
542 mode 2 form 1&2, multi session */
543 p[5] = 0xff; /* CD DA, DA accurate, RW supported,
544 RW corrected, C2 errors, ISRC,
545 UPC, Bar code */
546 p[6] = 0x2d | (bdrv_is_locked(s->qdev.dinfo->bdrv)? 2 : 0);
547 /* Locking supported, jumper present, eject, tray */
548 p[7] = 0; /* no volume & mute control, no
549 changer */
550 p[8] = (50 * 176) >> 8; // 50x read speed
551 p[9] = (50 * 176) & 0xff;
552 p[10] = 0 >> 8; // No volume
553 p[11] = 0 & 0xff;
554 p[12] = 2048 >> 8; // 2M buffer
555 p[13] = 2048 & 0xff;
556 p[14] = (16 * 176) >> 8; // 16x read speed current
557 p[15] = (16 * 176) & 0xff;
558 p[18] = (16 * 176) >> 8; // 16x write speed
559 p[19] = (16 * 176) & 0xff;
560 p[20] = (16 * 176) >> 8; // 16x write speed current
561 p[21] = (16 * 176) & 0xff;
562 return 22;
564 default:
565 return 0;
569 static int scsi_disk_emulate_mode_sense(SCSIRequest *req, uint8_t *outbuf)
571 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev);
572 BlockDriverState *bdrv = req->dev->dinfo->bdrv;
573 uint64_t nb_sectors;
574 int page, dbd, buflen;
575 uint8_t *p;
577 dbd = req->cmd.buf[1] & 0x8;
578 page = req->cmd.buf[2] & 0x3f;
579 DPRINTF("Mode Sense (page %d, len %zd)\n", page, req->cmd.xfer);
580 memset(outbuf, 0, req->cmd.xfer);
581 p = outbuf;
583 p[1] = 0; /* Default media type. */
584 p[3] = 0; /* Block descriptor length. */
585 if (bdrv_get_type_hint(bdrv) == BDRV_TYPE_CDROM ||
586 bdrv_is_read_only(bdrv)) {
587 p[2] = 0x80; /* Readonly. */
589 p += 4;
591 bdrv_get_geometry(bdrv, &nb_sectors);
592 if ((~dbd) & nb_sectors) {
593 outbuf[3] = 8; /* Block descriptor length */
594 nb_sectors /= s->cluster_size;
595 nb_sectors--;
596 if (nb_sectors > 0xffffff)
597 nb_sectors = 0xffffff;
598 p[0] = 0; /* media density code */
599 p[1] = (nb_sectors >> 16) & 0xff;
600 p[2] = (nb_sectors >> 8) & 0xff;
601 p[3] = nb_sectors & 0xff;
602 p[4] = 0; /* reserved */
603 p[5] = 0; /* bytes 5-7 are the sector size in bytes */
604 p[6] = s->cluster_size * 2;
605 p[7] = 0;
606 p += 8;
609 switch (page) {
610 case 0x04:
611 case 0x05:
612 case 0x08:
613 case 0x2a:
614 p += mode_sense_page(req, page, p);
615 break;
616 case 0x3f:
617 p += mode_sense_page(req, 0x08, p);
618 p += mode_sense_page(req, 0x2a, p);
619 break;
622 buflen = p - outbuf;
623 outbuf[0] = buflen - 4;
624 if (buflen > req->cmd.xfer)
625 buflen = req->cmd.xfer;
626 return buflen;
629 static int scsi_disk_emulate_read_toc(SCSIRequest *req, uint8_t *outbuf)
631 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev);
632 BlockDriverState *bdrv = req->dev->dinfo->bdrv;
633 int start_track, format, msf, toclen;
634 uint64_t nb_sectors;
636 msf = req->cmd.buf[1] & 2;
637 format = req->cmd.buf[2] & 0xf;
638 start_track = req->cmd.buf[6];
639 bdrv_get_geometry(bdrv, &nb_sectors);
640 DPRINTF("Read TOC (track %d format %d msf %d)\n", start_track, format, msf >> 1);
641 nb_sectors /= s->cluster_size;
642 switch (format) {
643 case 0:
644 toclen = cdrom_read_toc(nb_sectors, outbuf, msf, start_track);
645 break;
646 case 1:
647 /* multi session : only a single session defined */
648 toclen = 12;
649 memset(outbuf, 0, 12);
650 outbuf[1] = 0x0a;
651 outbuf[2] = 0x01;
652 outbuf[3] = 0x01;
653 break;
654 case 2:
655 toclen = cdrom_read_toc_raw(nb_sectors, outbuf, msf, start_track);
656 break;
657 default:
658 return -1;
660 if (toclen > req->cmd.xfer)
661 toclen = req->cmd.xfer;
662 return toclen;
665 static int scsi_disk_emulate_command(SCSIRequest *req, uint8_t *outbuf)
667 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev);
668 BlockDriverState *bdrv = req->dev->dinfo->bdrv;
669 uint64_t nb_sectors;
670 int buflen = 0;
672 switch (req->cmd.buf[0]) {
673 case TEST_UNIT_READY:
674 if (!bdrv_is_inserted(bdrv))
675 goto not_ready;
676 break;
677 case REQUEST_SENSE:
678 if (req->cmd.xfer < 4)
679 goto illegal_request;
680 memset(outbuf, 0, 4);
681 buflen = 4;
682 if (req->dev->sense.key == NOT_READY && req->cmd.xfer >= 18) {
683 memset(outbuf, 0, 18);
684 buflen = 18;
685 outbuf[7] = 10;
686 /* asc 0x3a, ascq 0: Medium not present */
687 outbuf[12] = 0x3a;
688 outbuf[13] = 0;
690 outbuf[0] = 0xf0;
691 outbuf[1] = 0;
692 outbuf[2] = req->dev->sense.key;
693 scsi_dev_clear_sense(req->dev);
694 break;
695 case INQUIRY:
696 buflen = scsi_disk_emulate_inquiry(req, outbuf);
697 if (buflen < 0)
698 goto illegal_request;
699 break;
700 case MODE_SENSE:
701 case MODE_SENSE_10:
702 buflen = scsi_disk_emulate_mode_sense(req, outbuf);
703 if (buflen < 0)
704 goto illegal_request;
705 break;
706 case READ_TOC:
707 buflen = scsi_disk_emulate_read_toc(req, outbuf);
708 if (buflen < 0)
709 goto illegal_request;
710 break;
711 case RESERVE:
712 if (req->cmd.buf[1] & 1)
713 goto illegal_request;
714 break;
715 case RESERVE_10:
716 if (req->cmd.buf[1] & 3)
717 goto illegal_request;
718 break;
719 case RELEASE:
720 if (req->cmd.buf[1] & 1)
721 goto illegal_request;
722 break;
723 case RELEASE_10:
724 if (req->cmd.buf[1] & 3)
725 goto illegal_request;
726 break;
727 case START_STOP:
728 if (bdrv_get_type_hint(bdrv) == BDRV_TYPE_CDROM && (req->cmd.buf[4] & 2)) {
729 /* load/eject medium */
730 bdrv_eject(bdrv, !(req->cmd.buf[4] & 1));
732 break;
733 case ALLOW_MEDIUM_REMOVAL:
734 bdrv_set_locked(bdrv, req->cmd.buf[4] & 1);
735 break;
736 case READ_CAPACITY:
737 /* The normal LEN field for this command is zero. */
738 memset(outbuf, 0, 8);
739 bdrv_get_geometry(bdrv, &nb_sectors);
740 if (!nb_sectors)
741 goto not_ready;
742 nb_sectors /= s->cluster_size;
743 /* Returned value is the address of the last sector. */
744 nb_sectors--;
745 /* Remember the new size for read/write sanity checking. */
746 s->max_lba = nb_sectors;
747 /* Clip to 2TB, instead of returning capacity modulo 2TB. */
748 if (nb_sectors > UINT32_MAX)
749 nb_sectors = UINT32_MAX;
750 outbuf[0] = (nb_sectors >> 24) & 0xff;
751 outbuf[1] = (nb_sectors >> 16) & 0xff;
752 outbuf[2] = (nb_sectors >> 8) & 0xff;
753 outbuf[3] = nb_sectors & 0xff;
754 outbuf[4] = 0;
755 outbuf[5] = 0;
756 outbuf[6] = s->cluster_size * 2;
757 outbuf[7] = 0;
758 buflen = 8;
759 break;
760 case SYNCHRONIZE_CACHE:
761 bdrv_flush(bdrv);
762 break;
763 case GET_CONFIGURATION:
764 memset(outbuf, 0, 8);
765 /* ??? This should probably return much more information. For now
766 just return the basic header indicating the CD-ROM profile. */
767 outbuf[7] = 8; // CD-ROM
768 buflen = 8;
769 break;
770 case SERVICE_ACTION_IN:
771 /* Service Action In subcommands. */
772 if ((req->cmd.buf[1] & 31) == 0x10) {
773 DPRINTF("SAI READ CAPACITY(16)\n");
774 memset(outbuf, 0, req->cmd.xfer);
775 bdrv_get_geometry(bdrv, &nb_sectors);
776 if (!nb_sectors)
777 goto not_ready;
778 nb_sectors /= s->cluster_size;
779 /* Returned value is the address of the last sector. */
780 nb_sectors--;
781 /* Remember the new size for read/write sanity checking. */
782 s->max_lba = nb_sectors;
783 outbuf[0] = (nb_sectors >> 56) & 0xff;
784 outbuf[1] = (nb_sectors >> 48) & 0xff;
785 outbuf[2] = (nb_sectors >> 40) & 0xff;
786 outbuf[3] = (nb_sectors >> 32) & 0xff;
787 outbuf[4] = (nb_sectors >> 24) & 0xff;
788 outbuf[5] = (nb_sectors >> 16) & 0xff;
789 outbuf[6] = (nb_sectors >> 8) & 0xff;
790 outbuf[7] = nb_sectors & 0xff;
791 outbuf[8] = 0;
792 outbuf[9] = 0;
793 outbuf[10] = s->cluster_size * 2;
794 outbuf[11] = 0;
795 /* Protection, exponent and lowest lba field left blank. */
796 buflen = req->cmd.xfer;
797 break;
799 DPRINTF("Unsupported Service Action In\n");
800 goto illegal_request;
801 case REPORT_LUNS:
802 if (req->cmd.xfer < 16)
803 goto illegal_request;
804 memset(outbuf, 0, 16);
805 outbuf[3] = 8;
806 buflen = 16;
807 break;
808 case VERIFY:
809 break;
810 default:
811 goto illegal_request;
813 scsi_req_set_status(req, GOOD, NO_SENSE);
814 return buflen;
816 not_ready:
817 scsi_req_set_status(req, CHECK_CONDITION, NOT_READY);
818 return 0;
820 illegal_request:
821 scsi_req_set_status(req, CHECK_CONDITION, ILLEGAL_REQUEST);
822 return 0;
825 /* Execute a scsi command. Returns the length of the data expected by the
826 command. This will be Positive for data transfers from the device
827 (eg. disk reads), negative for transfers to the device (eg. disk writes),
828 and zero if the command does not transfer any data. */
830 static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
831 uint8_t *buf, int lun)
833 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, d);
834 uint64_t lba;
835 uint32_t len;
836 int cmdlen;
837 int is_write;
838 uint8_t command;
839 uint8_t *outbuf;
840 SCSIDiskReq *r;
841 int rc;
843 command = buf[0];
844 r = scsi_find_request(s, tag);
845 if (r) {
846 BADF("Tag 0x%x already in use\n", tag);
847 scsi_cancel_io(d, tag);
849 /* ??? Tags are not unique for different luns. We only implement a
850 single lun, so this should not matter. */
851 r = scsi_new_request(d, tag, lun);
852 outbuf = (uint8_t *)r->iov.iov_base;
853 is_write = 0;
854 DPRINTF("Command: lun=%d tag=0x%x data=0x%02x", lun, tag, buf[0]);
855 switch (command >> 5) {
856 case 0:
857 lba = (uint64_t) buf[3] | ((uint64_t) buf[2] << 8) |
858 (((uint64_t) buf[1] & 0x1f) << 16);
859 len = buf[4];
860 cmdlen = 6;
861 break;
862 case 1:
863 case 2:
864 lba = (uint64_t) buf[5] | ((uint64_t) buf[4] << 8) |
865 ((uint64_t) buf[3] << 16) | ((uint64_t) buf[2] << 24);
866 len = buf[8] | (buf[7] << 8);
867 cmdlen = 10;
868 break;
869 case 4:
870 lba = (uint64_t) buf[9] | ((uint64_t) buf[8] << 8) |
871 ((uint64_t) buf[7] << 16) | ((uint64_t) buf[6] << 24) |
872 ((uint64_t) buf[5] << 32) | ((uint64_t) buf[4] << 40) |
873 ((uint64_t) buf[3] << 48) | ((uint64_t) buf[2] << 56);
874 len = buf[13] | (buf[12] << 8) | (buf[11] << 16) | (buf[10] << 24);
875 cmdlen = 16;
876 break;
877 case 5:
878 lba = (uint64_t) buf[5] | ((uint64_t) buf[4] << 8) |
879 ((uint64_t) buf[3] << 16) | ((uint64_t) buf[2] << 24);
880 len = buf[9] | (buf[8] << 8) | (buf[7] << 16) | (buf[6] << 24);
881 cmdlen = 12;
882 break;
883 default:
884 BADF("Unsupported command length, command %x\n", command);
885 goto fail;
887 #ifdef DEBUG_SCSI
889 int i;
890 for (i = 1; i < cmdlen; i++) {
891 printf(" 0x%02x", buf[i]);
893 printf("\n");
895 #endif
897 if (scsi_req_parse(&r->req, buf) != 0) {
898 BADF("Unsupported command length, command %x\n", command);
899 goto fail;
901 assert(r->req.cmd.len == cmdlen);
902 assert(r->req.cmd.lba == lba);
904 if (lun || buf[1] >> 5) {
905 /* Only LUN 0 supported. */
906 DPRINTF("Unimplemented LUN %d\n", lun ? lun : buf[1] >> 5);
907 if (command != REQUEST_SENSE && command != INQUIRY)
908 goto fail;
910 switch (command) {
911 case TEST_UNIT_READY:
912 case REQUEST_SENSE:
913 case INQUIRY:
914 case MODE_SENSE:
915 case MODE_SENSE_10:
916 case RESERVE:
917 case RESERVE_10:
918 case RELEASE:
919 case RELEASE_10:
920 case START_STOP:
921 case ALLOW_MEDIUM_REMOVAL:
922 case READ_CAPACITY:
923 case SYNCHRONIZE_CACHE:
924 case READ_TOC:
925 case GET_CONFIGURATION:
926 case SERVICE_ACTION_IN:
927 case REPORT_LUNS:
928 case VERIFY:
929 rc = scsi_disk_emulate_command(&r->req, outbuf);
930 if (rc > 0) {
931 r->iov.iov_len = rc;
932 } else {
933 scsi_req_complete(&r->req);
934 scsi_remove_request(r);
935 return 0;
937 break;
938 case READ_6:
939 case READ_10:
940 case READ_12:
941 case READ_16:
942 DPRINTF("Read (sector %" PRId64 ", count %d)\n", lba, len);
943 if (lba > s->max_lba)
944 goto illegal_lba;
945 r->sector = lba * s->cluster_size;
946 r->sector_count = len * s->cluster_size;
947 break;
948 case WRITE_6:
949 case WRITE_10:
950 case WRITE_12:
951 case WRITE_16:
952 DPRINTF("Write (sector %" PRId64 ", count %d)\n", lba, len);
953 if (lba > s->max_lba)
954 goto illegal_lba;
955 r->sector = lba * s->cluster_size;
956 r->sector_count = len * s->cluster_size;
957 is_write = 1;
958 break;
959 default:
960 DPRINTF("Unknown SCSI command (%2.2x)\n", buf[0]);
961 fail:
962 scsi_command_complete(r, CHECK_CONDITION, ILLEGAL_REQUEST);
963 return 0;
964 illegal_lba:
965 scsi_command_complete(r, CHECK_CONDITION, HARDWARE_ERROR);
966 return 0;
968 if (r->sector_count == 0 && r->iov.iov_len == 0) {
969 scsi_command_complete(r, GOOD, NO_SENSE);
971 len = r->sector_count * 512 + r->iov.iov_len;
972 if (is_write) {
973 return -len;
974 } else {
975 if (!r->sector_count)
976 r->sector_count = -1;
977 return len;
981 static void scsi_destroy(SCSIDevice *dev)
983 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
984 SCSIDiskReq *r;
986 while (!QTAILQ_EMPTY(&s->qdev.requests)) {
987 r = DO_UPCAST(SCSIDiskReq, req, QTAILQ_FIRST(&s->qdev.requests));
988 scsi_remove_request(r);
990 drive_uninit(s->qdev.dinfo);
993 static int scsi_disk_initfn(SCSIDevice *dev)
995 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
996 uint64_t nb_sectors;
998 if (!s->qdev.dinfo || !s->qdev.dinfo->bdrv) {
999 qemu_error("scsi-disk: drive property not set\n");
1000 return -1;
1003 if (bdrv_get_type_hint(s->qdev.dinfo->bdrv) == BDRV_TYPE_CDROM) {
1004 s->cluster_size = 4;
1005 } else {
1006 s->cluster_size = 1;
1008 s->qdev.blocksize = 512 * s->cluster_size;
1009 s->qdev.type = TYPE_DISK;
1010 bdrv_get_geometry(s->qdev.dinfo->bdrv, &nb_sectors);
1011 nb_sectors /= s->cluster_size;
1012 if (nb_sectors)
1013 nb_sectors--;
1014 s->max_lba = nb_sectors;
1015 qemu_add_vm_change_state_handler(scsi_dma_restart_cb, s);
1016 return 0;
1019 static SCSIDeviceInfo scsi_disk_info = {
1020 .qdev.name = "scsi-disk",
1021 .qdev.desc = "virtual scsi disk or cdrom",
1022 .qdev.size = sizeof(SCSIDiskState),
1023 .init = scsi_disk_initfn,
1024 .destroy = scsi_destroy,
1025 .send_command = scsi_send_command,
1026 .read_data = scsi_read_data,
1027 .write_data = scsi_write_data,
1028 .cancel_io = scsi_cancel_io,
1029 .get_buf = scsi_get_buf,
1030 .qdev.props = (Property[]) {
1031 DEFINE_PROP_DRIVE("drive", SCSIDiskState, qdev.dinfo),
1032 DEFINE_PROP_END_OF_LIST(),
1036 static void scsi_disk_register_devices(void)
1038 scsi_qdev_register(&scsi_disk_info);
1040 device_init(scsi_disk_register_devices)