]> git.proxmox.com Git - qemu.git/blame - hw/scsi-disk.c
virtio-blk: Handle immediate flush failure properly
[qemu.git] / hw / scsi-disk.c
CommitLineData
2e5d83bb
PB
1/*
2 * SCSI Device emulation
3 *
4 * Copyright (c) 2006 CodeSourcery.
5 * Based on code by Fabrice Bellard
6 *
7 * Written by Paul Brook
ad3cea42
AT
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.
2e5d83bb
PB
14 *
15 * This code is licenced under the LGPL.
a917d384
PB
16 *
17 * Note that this file only handles the SCSI architecture model and device
1d4db89c
AZ
18 * commands. Emulation of interface/link layer protocols is handled by
19 * the host adapter emulator.
2e5d83bb
PB
20 */
21
22//#define DEBUG_SCSI
23
24#ifdef DEBUG_SCSI
001faf32
BS
25#define DPRINTF(fmt, ...) \
26do { printf("scsi-disk: " fmt , ## __VA_ARGS__); } while (0)
2e5d83bb 27#else
001faf32 28#define DPRINTF(fmt, ...) do {} while(0)
2e5d83bb
PB
29#endif
30
001faf32
BS
31#define BADF(fmt, ...) \
32do { fprintf(stderr, "scsi-disk: " fmt , ## __VA_ARGS__); } while (0)
2e5d83bb 33
87ecb68b 34#include "qemu-common.h"
2f792016 35#include "qemu-error.h"
43b443b6 36#include "scsi.h"
0d65e1f8 37#include "scsi-defs.h"
666daa68 38#include "sysemu.h"
2446333c 39#include "blockdev.h"
22864256 40
f0f72ffe 41#define SCSI_DMA_BUF_SIZE 131072
57575058 42#define SCSI_MAX_INQUIRY_LEN 256
a917d384 43
5dba48a8
KW
44#define SCSI_REQ_STATUS_RETRY 0x01
45#define SCSI_REQ_STATUS_RETRY_TYPE_MASK 0x06
46#define SCSI_REQ_STATUS_RETRY_READ 0x00
47#define SCSI_REQ_STATUS_RETRY_WRITE 0x02
78ced65e 48#define SCSI_REQ_STATUS_RETRY_FLUSH 0x04
ea8a5d7f 49
d52affa7
GH
50typedef struct SCSIDiskState SCSIDiskState;
51
4c41d2ef
GH
52typedef struct SCSIDiskReq {
53 SCSIRequest req;
e035b43d 54 /* ??? We should probably keep track of whether the data transfer is
2e5d83bb 55 a read or a write. Currently we rely on the host getting it right. */
a917d384 56 /* Both sector and sector_count are in terms of qemu 512 byte blocks. */
e035b43d
AL
57 uint64_t sector;
58 uint32_t sector_count;
c87c0672
AL
59 struct iovec iov;
60 QEMUIOVector qiov;
ea8a5d7f 61 uint32_t status;
4c41d2ef 62} SCSIDiskReq;
a917d384 63
d52affa7 64struct SCSIDiskState
a917d384 65{
d52affa7 66 SCSIDevice qdev;
428c149b 67 BlockDriverState *bs;
a917d384
PB
68 /* The qemu block layer uses a fixed 512 byte sector size.
69 This is the number of 512 byte blocks in a single scsi sector. */
70 int cluster_size;
274fb0e1 71 uint64_t max_lba;
213189ab 72 QEMUBH *bh;
383b4d9b 73 char *version;
a0fef654 74 char *serial;
2e5d83bb
PB
75};
76
5dba48a8 77static int scsi_handle_rw_error(SCSIDiskReq *r, int error, int type);
78ced65e 78static int scsi_disk_emulate_command(SCSIDiskReq *r, uint8_t *outbuf);
5dba48a8 79
72aef731
CH
80static SCSIDiskReq *scsi_new_request(SCSIDiskState *s, uint32_t tag,
81 uint32_t lun)
2e5d83bb 82{
89b08ae1 83 SCSIRequest *req;
4c41d2ef 84 SCSIDiskReq *r;
a917d384 85
72aef731 86 req = scsi_req_alloc(sizeof(SCSIDiskReq), &s->qdev, tag, lun);
89b08ae1 87 r = DO_UPCAST(SCSIDiskReq, req, req);
72aef731 88 r->iov.iov_base = qemu_blockalign(s->bs, SCSI_DMA_BUF_SIZE);
a917d384 89 return r;
2e5d83bb
PB
90}
91
4c41d2ef 92static void scsi_remove_request(SCSIDiskReq *r)
4d611c9a 93{
f8a83245 94 qemu_vfree(r->iov.iov_base);
89b08ae1 95 scsi_req_free(&r->req);
4d611c9a
PB
96}
97
4c41d2ef 98static SCSIDiskReq *scsi_find_request(SCSIDiskState *s, uint32_t tag)
4d611c9a 99{
89b08ae1 100 return DO_UPCAST(SCSIDiskReq, req, scsi_req_find(&s->qdev, tag));
a917d384
PB
101}
102
ed3a34a3
GH
103static void scsi_req_set_status(SCSIRequest *req, int status, int sense_code)
104{
105 req->status = status;
106 scsi_dev_set_sense(req->dev, sense_code);
107}
108
a917d384 109/* Helper function for command completion. */
4c41d2ef 110static void scsi_command_complete(SCSIDiskReq *r, int status, int sense)
a917d384 111{
4c41d2ef
GH
112 DPRINTF("Command complete tag=0x%x status=%d sense=%d\n",
113 r->req.tag, status, sense);
ed3a34a3
GH
114 scsi_req_set_status(&r->req, status, sense);
115 scsi_req_complete(&r->req);
89b08ae1 116 scsi_remove_request(r);
4d611c9a
PB
117}
118
119/* Cancel a pending data transfer. */
8ccc2ace 120static void scsi_cancel_io(SCSIDevice *d, uint32_t tag)
4d611c9a 121{
d52affa7 122 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, d);
4c41d2ef 123 SCSIDiskReq *r;
a917d384
PB
124 DPRINTF("Cancel tag=0x%x\n", tag);
125 r = scsi_find_request(s, tag);
126 if (r) {
4c41d2ef
GH
127 if (r->req.aiocb)
128 bdrv_aio_cancel(r->req.aiocb);
129 r->req.aiocb = NULL;
a917d384
PB
130 scsi_remove_request(r);
131 }
132}
133
134static void scsi_read_complete(void * opaque, int ret)
135{
4c41d2ef 136 SCSIDiskReq *r = (SCSIDiskReq *)opaque;
5dba48a8 137 int n;
a917d384 138
3e94cb02
JK
139 r->req.aiocb = NULL;
140
a917d384 141 if (ret) {
5dba48a8
KW
142 if (scsi_handle_rw_error(r, -ret, SCSI_REQ_STATUS_RETRY_READ)) {
143 return;
144 }
4d611c9a 145 }
5dba48a8 146
aa2b1e89 147 DPRINTF("Data ready tag=0x%x len=%zd\n", r->req.tag, r->iov.iov_len);
a917d384 148
5dba48a8
KW
149 n = r->iov.iov_len / 512;
150 r->sector += n;
151 r->sector_count -= n;
4c41d2ef 152 r->req.bus->complete(r->req.bus, SCSI_REASON_DATA, r->req.tag, r->iov.iov_len);
4d611c9a
PB
153}
154
5dba48a8
KW
155
156static void scsi_read_request(SCSIDiskReq *r)
2e5d83bb 157{
5dba48a8 158 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
2e5d83bb
PB
159 uint32_t n;
160
a917d384 161 if (r->sector_count == (uint32_t)-1) {
aa2b1e89 162 DPRINTF("Read buf_len=%zd\n", r->iov.iov_len);
a917d384 163 r->sector_count = 0;
4c41d2ef 164 r->req.bus->complete(r->req.bus, SCSI_REASON_DATA, r->req.tag, r->iov.iov_len);
a917d384 165 return;
2e5d83bb 166 }
a917d384
PB
167 DPRINTF("Read sector_count=%d\n", r->sector_count);
168 if (r->sector_count == 0) {
0d65e1f8 169 scsi_command_complete(r, GOOD, NO_SENSE);
a917d384 170 return;
2e5d83bb
PB
171 }
172
a917d384
PB
173 n = r->sector_count;
174 if (n > SCSI_DMA_BUF_SIZE / 512)
175 n = SCSI_DMA_BUF_SIZE / 512;
176
c87c0672
AL
177 r->iov.iov_len = n * 512;
178 qemu_iovec_init_external(&r->qiov, &r->iov, 1);
428c149b 179 r->req.aiocb = bdrv_aio_readv(s->bs, r->sector, &r->qiov, n,
c87c0672 180 scsi_read_complete, r);
4c41d2ef 181 if (r->req.aiocb == NULL)
0d65e1f8 182 scsi_command_complete(r, CHECK_CONDITION, HARDWARE_ERROR);
2e5d83bb
PB
183}
184
5dba48a8
KW
185/* Read more data from scsi device into buffer. */
186static void scsi_read_data(SCSIDevice *d, uint32_t tag)
ea8a5d7f 187{
5dba48a8
KW
188 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, d);
189 SCSIDiskReq *r;
190
191 r = scsi_find_request(s, tag);
192 if (!r) {
193 BADF("Bad read tag 0x%x\n", tag);
194 /* ??? This is the wrong error. */
195 scsi_command_complete(r, CHECK_CONDITION, HARDWARE_ERROR);
196 return;
197 }
198
199 /* No data transfer may already be in progress */
200 assert(r->req.aiocb == NULL);
201
202 scsi_read_request(r);
203}
204
205static int scsi_handle_rw_error(SCSIDiskReq *r, int error, int type)
206{
207 int is_read = (type == SCSI_REQ_STATUS_RETRY_READ);
4c41d2ef 208 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
5dba48a8 209 BlockErrorAction action = bdrv_get_on_error(s->bs, is_read);
ea8a5d7f 210
380f640f 211 if (action == BLOCK_ERR_IGNORE) {
5dba48a8 212 bdrv_mon_event(s->bs, BDRV_ACTION_IGNORE, is_read);
ea8a5d7f 213 return 0;
380f640f 214 }
ea8a5d7f
AL
215
216 if ((error == ENOSPC && action == BLOCK_ERR_STOP_ENOSPC)
217 || action == BLOCK_ERR_STOP_ANY) {
5dba48a8
KW
218
219 type &= SCSI_REQ_STATUS_RETRY_TYPE_MASK;
220 r->status |= SCSI_REQ_STATUS_RETRY | type;
221
222 bdrv_mon_event(s->bs, BDRV_ACTION_STOP, is_read);
554a310b 223 vm_stop(0);
ea8a5d7f 224 } else {
5dba48a8
KW
225 if (type == SCSI_REQ_STATUS_RETRY_READ) {
226 r->req.bus->complete(r->req.bus, SCSI_REASON_DATA, r->req.tag, 0);
227 }
0d65e1f8
GH
228 scsi_command_complete(r, CHECK_CONDITION,
229 HARDWARE_ERROR);
5dba48a8 230 bdrv_mon_event(s->bs, BDRV_ACTION_REPORT, is_read);
ea8a5d7f
AL
231 }
232
233 return 1;
234}
235
4d611c9a
PB
236static void scsi_write_complete(void * opaque, int ret)
237{
4c41d2ef 238 SCSIDiskReq *r = (SCSIDiskReq *)opaque;
a917d384 239 uint32_t len;
ea8a5d7f
AL
240 uint32_t n;
241
4c41d2ef 242 r->req.aiocb = NULL;
4d611c9a
PB
243
244 if (ret) {
5dba48a8 245 if (scsi_handle_rw_error(r, -ret, SCSI_REQ_STATUS_RETRY_WRITE)) {
ea8a5d7f 246 return;
5dba48a8 247 }
4d611c9a
PB
248 }
249
c87c0672 250 n = r->iov.iov_len / 512;
ea8a5d7f
AL
251 r->sector += n;
252 r->sector_count -= n;
a917d384 253 if (r->sector_count == 0) {
0d65e1f8 254 scsi_command_complete(r, GOOD, NO_SENSE);
a917d384
PB
255 } else {
256 len = r->sector_count * 512;
257 if (len > SCSI_DMA_BUF_SIZE) {
258 len = SCSI_DMA_BUF_SIZE;
259 }
c87c0672 260 r->iov.iov_len = len;
4c41d2ef
GH
261 DPRINTF("Write complete tag=0x%x more=%d\n", r->req.tag, len);
262 r->req.bus->complete(r->req.bus, SCSI_REASON_DATA, r->req.tag, len);
4d611c9a 263 }
4d611c9a
PB
264}
265
4c41d2ef 266static void scsi_write_request(SCSIDiskReq *r)
ea8a5d7f 267{
4c41d2ef 268 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
ea8a5d7f
AL
269 uint32_t n;
270
c87c0672 271 n = r->iov.iov_len / 512;
ea8a5d7f 272 if (n) {
c87c0672 273 qemu_iovec_init_external(&r->qiov, &r->iov, 1);
428c149b 274 r->req.aiocb = bdrv_aio_writev(s->bs, r->sector, &r->qiov, n,
c87c0672 275 scsi_write_complete, r);
4c41d2ef 276 if (r->req.aiocb == NULL)
0d65e1f8
GH
277 scsi_command_complete(r, CHECK_CONDITION,
278 HARDWARE_ERROR);
ea8a5d7f
AL
279 } else {
280 /* Invoke completion routine to fetch data from host. */
281 scsi_write_complete(r, 0);
282 }
283}
284
4d611c9a
PB
285/* Write data to a scsi device. Returns nonzero on failure.
286 The transfer may complete asynchronously. */
8ccc2ace 287static int scsi_write_data(SCSIDevice *d, uint32_t tag)
2e5d83bb 288{
d52affa7 289 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, d);
4c41d2ef 290 SCSIDiskReq *r;
2e5d83bb 291
a917d384
PB
292 DPRINTF("Write data tag=0x%x\n", tag);
293 r = scsi_find_request(s, tag);
294 if (!r) {
295 BADF("Bad write tag 0x%x\n", tag);
0d65e1f8 296 scsi_command_complete(r, CHECK_CONDITION, HARDWARE_ERROR);
2e5d83bb
PB
297 return 1;
298 }
ea8a5d7f 299
5dba48a8
KW
300 /* No data transfer may already be in progress */
301 assert(r->req.aiocb == NULL);
ea8a5d7f
AL
302
303 scsi_write_request(r);
2e5d83bb 304
a917d384
PB
305 return 0;
306}
2e5d83bb 307
213189ab 308static void scsi_dma_restart_bh(void *opaque)
ea8a5d7f 309{
d52affa7 310 SCSIDiskState *s = opaque;
9af99d98
GH
311 SCSIRequest *req;
312 SCSIDiskReq *r;
213189ab
MA
313
314 qemu_bh_delete(s->bh);
315 s->bh = NULL;
ea8a5d7f 316
9af99d98
GH
317 QTAILQ_FOREACH(req, &s->qdev.requests, next) {
318 r = DO_UPCAST(SCSIDiskReq, req, req);
ea8a5d7f 319 if (r->status & SCSI_REQ_STATUS_RETRY) {
5dba48a8 320 int status = r->status;
78ced65e
KW
321 int ret;
322
5dba48a8
KW
323 r->status &=
324 ~(SCSI_REQ_STATUS_RETRY | SCSI_REQ_STATUS_RETRY_TYPE_MASK);
325
326 switch (status & SCSI_REQ_STATUS_RETRY_TYPE_MASK) {
327 case SCSI_REQ_STATUS_RETRY_READ:
328 scsi_read_request(r);
329 break;
330 case SCSI_REQ_STATUS_RETRY_WRITE:
331 scsi_write_request(r);
332 break;
78ced65e
KW
333 case SCSI_REQ_STATUS_RETRY_FLUSH:
334 ret = scsi_disk_emulate_command(r, r->iov.iov_base);
335 if (ret == 0) {
336 scsi_command_complete(r, GOOD, NO_SENSE);
337 }
5dba48a8 338 }
ea8a5d7f 339 }
ea8a5d7f
AL
340 }
341}
342
213189ab
MA
343static void scsi_dma_restart_cb(void *opaque, int running, int reason)
344{
d52affa7 345 SCSIDiskState *s = opaque;
213189ab
MA
346
347 if (!running)
348 return;
349
350 if (!s->bh) {
351 s->bh = qemu_bh_new(scsi_dma_restart_bh, s);
352 qemu_bh_schedule(s->bh);
353 }
354}
355
a917d384 356/* Return a pointer to the data buffer. */
8ccc2ace 357static uint8_t *scsi_get_buf(SCSIDevice *d, uint32_t tag)
a917d384 358{
d52affa7 359 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, d);
4c41d2ef 360 SCSIDiskReq *r;
2e5d83bb 361
a917d384
PB
362 r = scsi_find_request(s, tag);
363 if (!r) {
364 BADF("Bad buffer tag 0x%x\n", tag);
365 return NULL;
4d611c9a 366 }
3f4cb3d3 367 return (uint8_t *)r->iov.iov_base;
2e5d83bb
PB
368}
369
0b06c059
GH
370static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf)
371{
383b4d9b 372 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev);
0b06c059
GH
373 int buflen = 0;
374
375 if (req->cmd.buf[1] & 0x2) {
376 /* Command support data - optional, not implemented */
377 BADF("optional INQUIRY command support request not implemented\n");
378 return -1;
379 }
380
381 if (req->cmd.buf[1] & 0x1) {
382 /* Vital product data */
383 uint8_t page_code = req->cmd.buf[2];
384 if (req->cmd.xfer < 4) {
385 BADF("Error: Inquiry (EVPD[%02X]) buffer size %zd is "
386 "less than 4\n", page_code, req->cmd.xfer);
387 return -1;
388 }
389
428c149b 390 if (bdrv_get_type_hint(s->bs) == BDRV_TYPE_CDROM) {
0b06c059
GH
391 outbuf[buflen++] = 5;
392 } else {
393 outbuf[buflen++] = 0;
394 }
395 outbuf[buflen++] = page_code ; // this page
396 outbuf[buflen++] = 0x00;
397
398 switch (page_code) {
399 case 0x00: /* Supported page codes, mandatory */
400 DPRINTF("Inquiry EVPD[Supported pages] "
401 "buffer size %zd\n", req->cmd.xfer);
ee3659e3 402 outbuf[buflen++] = 4; // number of pages
0b06c059
GH
403 outbuf[buflen++] = 0x00; // list of supported pages (this page)
404 outbuf[buflen++] = 0x80; // unit serial number
405 outbuf[buflen++] = 0x83; // device identification
ee3659e3 406 outbuf[buflen++] = 0xb0; // block device characteristics
0b06c059
GH
407 break;
408
409 case 0x80: /* Device serial number, optional */
410 {
a0fef654 411 int l = strlen(s->serial);
0b06c059
GH
412
413 if (l > req->cmd.xfer)
414 l = req->cmd.xfer;
415 if (l > 20)
416 l = 20;
417
418 DPRINTF("Inquiry EVPD[Serial number] "
419 "buffer size %zd\n", req->cmd.xfer);
420 outbuf[buflen++] = l;
a0fef654 421 memcpy(outbuf+buflen, s->serial, l);
0b06c059
GH
422 buflen += l;
423 break;
424 }
425
426 case 0x83: /* Device identification page, mandatory */
427 {
428 int max_len = 255 - 8;
428c149b 429 int id_len = strlen(bdrv_get_device_name(s->bs));
0b06c059
GH
430
431 if (id_len > max_len)
432 id_len = max_len;
433 DPRINTF("Inquiry EVPD[Device identification] "
434 "buffer size %zd\n", req->cmd.xfer);
435
436 outbuf[buflen++] = 3 + id_len;
437 outbuf[buflen++] = 0x2; // ASCII
438 outbuf[buflen++] = 0; // not officially assigned
439 outbuf[buflen++] = 0; // reserved
440 outbuf[buflen++] = id_len; // length of data following
441
428c149b 442 memcpy(outbuf+buflen, bdrv_get_device_name(s->bs), id_len);
0b06c059
GH
443 buflen += id_len;
444 break;
445 }
ee3659e3
CH
446 case 0xb0: /* block device characteristics */
447 {
8cfacf07
CH
448 unsigned int min_io_size =
449 s->qdev.conf.min_io_size / s->qdev.blocksize;
450 unsigned int opt_io_size =
451 s->qdev.conf.opt_io_size / s->qdev.blocksize;
ee3659e3
CH
452
453 /* required VPD size with unmap support */
454 outbuf[3] = buflen = 0x3c;
455
456 memset(outbuf + 4, 0, buflen - 4);
457
458 /* optimal transfer length granularity */
459 outbuf[6] = (min_io_size >> 8) & 0xff;
460 outbuf[7] = min_io_size & 0xff;
461
462 /* optimal transfer length */
463 outbuf[12] = (opt_io_size >> 24) & 0xff;
464 outbuf[13] = (opt_io_size >> 16) & 0xff;
465 outbuf[14] = (opt_io_size >> 8) & 0xff;
466 outbuf[15] = opt_io_size & 0xff;
467 break;
468 }
0b06c059
GH
469 default:
470 BADF("Error: unsupported Inquiry (EVPD[%02X]) "
471 "buffer size %zd\n", page_code, req->cmd.xfer);
472 return -1;
473 }
474 /* done with EVPD */
475 return buflen;
476 }
477
478 /* Standard INQUIRY data */
479 if (req->cmd.buf[2] != 0) {
480 BADF("Error: Inquiry (STANDARD) page or code "
481 "is non-zero [%02X]\n", req->cmd.buf[2]);
482 return -1;
483 }
484
485 /* PAGE CODE == 0 */
486 if (req->cmd.xfer < 5) {
487 BADF("Error: Inquiry (STANDARD) buffer size %zd "
488 "is less than 5\n", req->cmd.xfer);
489 return -1;
490 }
491
0b06c059
GH
492 buflen = req->cmd.xfer;
493 if (buflen > SCSI_MAX_INQUIRY_LEN)
494 buflen = SCSI_MAX_INQUIRY_LEN;
495
496 memset(outbuf, 0, buflen);
497
498 if (req->lun || req->cmd.buf[1] >> 5) {
499 outbuf[0] = 0x7f; /* LUN not supported */
500 return buflen;
501 }
502
428c149b 503 if (bdrv_get_type_hint(s->bs) == BDRV_TYPE_CDROM) {
0b06c059
GH
504 outbuf[0] = 5;
505 outbuf[1] = 0x80;
550fe6c6 506 memcpy(&outbuf[16], "QEMU CD-ROM ", 16);
0b06c059
GH
507 } else {
508 outbuf[0] = 0;
550fe6c6 509 memcpy(&outbuf[16], "QEMU HARDDISK ", 16);
0b06c059 510 }
550fe6c6 511 memcpy(&outbuf[8], "QEMU ", 8);
314b1811 512 memset(&outbuf[32], 0, 4);
552fee93 513 memcpy(&outbuf[32], s->version, MIN(4, strlen(s->version)));
99aba0c4
CH
514 /*
515 * We claim conformance to SPC-3, which is required for guests
516 * to ask for modern features like READ CAPACITY(16) or the
517 * block characteristics VPD page by default. Not all of SPC-3
518 * is actually implemented, but we're good enough.
519 */
ee3659e3 520 outbuf[2] = 5;
0b06c059 521 outbuf[3] = 2; /* Format 2 */
ad3cea42
AT
522
523 if (buflen > 36) {
524 outbuf[4] = buflen - 5; /* Additional Length = (Len - 1) - 4 */
525 } else {
526 /* If the allocation length of CDB is too small,
527 the additional length is not adjusted */
528 outbuf[4] = 36 - 5;
529 }
530
0b06c059
GH
531 /* Sync data transfer and TCQ. */
532 outbuf[7] = 0x10 | (req->bus->tcq ? 0x02 : 0);
533 return buflen;
534}
535
282ab04e
BK
536static int mode_sense_page(SCSIRequest *req, int page, uint8_t *p,
537 int page_control)
ebddfcbe
GH
538{
539 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev);
428c149b 540 BlockDriverState *bdrv = s->bs;
ebddfcbe
GH
541 int cylinders, heads, secs;
542
282ab04e
BK
543 /*
544 * If Changeable Values are requested, a mask denoting those mode parameters
545 * that are changeable shall be returned. As we currently don't support
546 * parameter changes via MODE_SELECT all bits are returned set to zero.
547 * The buffer was already menset to zero by the caller of this function.
548 */
ebddfcbe
GH
549 switch (page) {
550 case 4: /* Rigid disk device geometry page. */
551 p[0] = 4;
552 p[1] = 0x16;
282ab04e
BK
553 if (page_control == 1) { /* Changeable Values */
554 return p[1] + 2;
555 }
ebddfcbe
GH
556 /* if a geometry hint is available, use it */
557 bdrv_get_geometry_hint(bdrv, &cylinders, &heads, &secs);
558 p[2] = (cylinders >> 16) & 0xff;
559 p[3] = (cylinders >> 8) & 0xff;
560 p[4] = cylinders & 0xff;
561 p[5] = heads & 0xff;
562 /* Write precomp start cylinder, disabled */
563 p[6] = (cylinders >> 16) & 0xff;
564 p[7] = (cylinders >> 8) & 0xff;
565 p[8] = cylinders & 0xff;
566 /* Reduced current start cylinder, disabled */
567 p[9] = (cylinders >> 16) & 0xff;
568 p[10] = (cylinders >> 8) & 0xff;
569 p[11] = cylinders & 0xff;
570 /* Device step rate [ns], 200ns */
571 p[12] = 0;
572 p[13] = 200;
573 /* Landing zone cylinder */
574 p[14] = 0xff;
575 p[15] = 0xff;
576 p[16] = 0xff;
577 /* Medium rotation rate [rpm], 5400 rpm */
578 p[20] = (5400 >> 8) & 0xff;
579 p[21] = 5400 & 0xff;
282ab04e 580 return p[1] + 2;
ebddfcbe
GH
581
582 case 5: /* Flexible disk device geometry page. */
583 p[0] = 5;
584 p[1] = 0x1e;
282ab04e
BK
585 if (page_control == 1) { /* Changeable Values */
586 return p[1] + 2;
587 }
ebddfcbe
GH
588 /* Transfer rate [kbit/s], 5Mbit/s */
589 p[2] = 5000 >> 8;
590 p[3] = 5000 & 0xff;
591 /* if a geometry hint is available, use it */
592 bdrv_get_geometry_hint(bdrv, &cylinders, &heads, &secs);
593 p[4] = heads & 0xff;
594 p[5] = secs & 0xff;
595 p[6] = s->cluster_size * 2;
596 p[8] = (cylinders >> 8) & 0xff;
597 p[9] = cylinders & 0xff;
598 /* Write precomp start cylinder, disabled */
599 p[10] = (cylinders >> 8) & 0xff;
600 p[11] = cylinders & 0xff;
601 /* Reduced current start cylinder, disabled */
602 p[12] = (cylinders >> 8) & 0xff;
603 p[13] = cylinders & 0xff;
604 /* Device step rate [100us], 100us */
605 p[14] = 0;
606 p[15] = 1;
607 /* Device step pulse width [us], 1us */
608 p[16] = 1;
609 /* Device head settle delay [100us], 100us */
610 p[17] = 0;
611 p[18] = 1;
612 /* Motor on delay [0.1s], 0.1s */
613 p[19] = 1;
614 /* Motor off delay [0.1s], 0.1s */
615 p[20] = 1;
616 /* Medium rotation rate [rpm], 5400 rpm */
617 p[28] = (5400 >> 8) & 0xff;
618 p[29] = 5400 & 0xff;
282ab04e 619 return p[1] + 2;
ebddfcbe
GH
620
621 case 8: /* Caching page. */
622 p[0] = 8;
623 p[1] = 0x12;
282ab04e
BK
624 if (page_control == 1) { /* Changeable Values */
625 return p[1] + 2;
626 }
428c149b 627 if (bdrv_enable_write_cache(s->bs)) {
ebddfcbe
GH
628 p[2] = 4; /* WCE */
629 }
282ab04e 630 return p[1] + 2;
ebddfcbe
GH
631
632 case 0x2a: /* CD Capabilities and Mechanical Status page. */
633 if (bdrv_get_type_hint(bdrv) != BDRV_TYPE_CDROM)
634 return 0;
635 p[0] = 0x2a;
636 p[1] = 0x14;
282ab04e
BK
637 if (page_control == 1) { /* Changeable Values */
638 return p[1] + 2;
639 }
ebddfcbe
GH
640 p[2] = 3; // CD-R & CD-RW read
641 p[3] = 0; // Writing not supported
642 p[4] = 0x7f; /* Audio, composite, digital out,
643 mode 2 form 1&2, multi session */
644 p[5] = 0xff; /* CD DA, DA accurate, RW supported,
645 RW corrected, C2 errors, ISRC,
646 UPC, Bar code */
428c149b 647 p[6] = 0x2d | (bdrv_is_locked(s->bs)? 2 : 0);
ebddfcbe
GH
648 /* Locking supported, jumper present, eject, tray */
649 p[7] = 0; /* no volume & mute control, no
650 changer */
651 p[8] = (50 * 176) >> 8; // 50x read speed
652 p[9] = (50 * 176) & 0xff;
653 p[10] = 0 >> 8; // No volume
654 p[11] = 0 & 0xff;
655 p[12] = 2048 >> 8; // 2M buffer
656 p[13] = 2048 & 0xff;
657 p[14] = (16 * 176) >> 8; // 16x read speed current
658 p[15] = (16 * 176) & 0xff;
659 p[18] = (16 * 176) >> 8; // 16x write speed
660 p[19] = (16 * 176) & 0xff;
661 p[20] = (16 * 176) >> 8; // 16x write speed current
662 p[21] = (16 * 176) & 0xff;
282ab04e 663 return p[1] + 2;
ebddfcbe
GH
664
665 default:
666 return 0;
667 }
668}
669
670static int scsi_disk_emulate_mode_sense(SCSIRequest *req, uint8_t *outbuf)
671{
672 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev);
ebddfcbe 673 uint64_t nb_sectors;
282ab04e 674 int page, dbd, buflen, page_control;
ebddfcbe 675 uint8_t *p;
ce512ee1 676 uint8_t dev_specific_param;
ebddfcbe
GH
677
678 dbd = req->cmd.buf[1] & 0x8;
679 page = req->cmd.buf[2] & 0x3f;
282ab04e 680 page_control = (req->cmd.buf[2] & 0xc0) >> 6;
aa2b1e89
BK
681 DPRINTF("Mode Sense(%d) (page %d, xfer %zd, page_control %d)\n",
682 (req->cmd.buf[0] == MODE_SENSE) ? 6 : 10, page, req->cmd.xfer, page_control);
ebddfcbe
GH
683 memset(outbuf, 0, req->cmd.xfer);
684 p = outbuf;
685
0056dcc1 686 if (bdrv_is_read_only(s->bs)) {
ce512ee1
BK
687 dev_specific_param = 0x80; /* Readonly. */
688 } else {
689 dev_specific_param = 0x00;
690 }
691
692 if (req->cmd.buf[0] == MODE_SENSE) {
693 p[1] = 0; /* Default media type. */
694 p[2] = dev_specific_param;
695 p[3] = 0; /* Block descriptor length. */
696 p += 4;
697 } else { /* MODE_SENSE_10 */
698 p[2] = 0; /* Default media type. */
699 p[3] = dev_specific_param;
700 p[6] = p[7] = 0; /* Block descriptor length. */
701 p += 8;
ebddfcbe 702 }
ebddfcbe 703
428c149b 704 bdrv_get_geometry(s->bs, &nb_sectors);
333d50fe 705 if (!dbd && nb_sectors) {
ce512ee1
BK
706 if (req->cmd.buf[0] == MODE_SENSE) {
707 outbuf[3] = 8; /* Block descriptor length */
708 } else { /* MODE_SENSE_10 */
709 outbuf[7] = 8; /* Block descriptor length */
710 }
ebddfcbe 711 nb_sectors /= s->cluster_size;
ebddfcbe 712 if (nb_sectors > 0xffffff)
2488b740 713 nb_sectors = 0;
ebddfcbe
GH
714 p[0] = 0; /* media density code */
715 p[1] = (nb_sectors >> 16) & 0xff;
716 p[2] = (nb_sectors >> 8) & 0xff;
717 p[3] = nb_sectors & 0xff;
718 p[4] = 0; /* reserved */
719 p[5] = 0; /* bytes 5-7 are the sector size in bytes */
720 p[6] = s->cluster_size * 2;
721 p[7] = 0;
722 p += 8;
723 }
724
282ab04e
BK
725 if (page_control == 3) { /* Saved Values */
726 return -1; /* ILLEGAL_REQUEST */
727 }
728
ebddfcbe
GH
729 switch (page) {
730 case 0x04:
731 case 0x05:
732 case 0x08:
733 case 0x2a:
282ab04e 734 p += mode_sense_page(req, page, p, page_control);
ebddfcbe
GH
735 break;
736 case 0x3f:
282ab04e
BK
737 p += mode_sense_page(req, 0x08, p, page_control);
738 p += mode_sense_page(req, 0x2a, p, page_control);
ebddfcbe 739 break;
a9c17b2b
BK
740 default:
741 return -1; /* ILLEGAL_REQUEST */
ebddfcbe
GH
742 }
743
744 buflen = p - outbuf;
ce512ee1
BK
745 /*
746 * The mode data length field specifies the length in bytes of the
747 * following data that is available to be transferred. The mode data
748 * length does not include itself.
749 */
750 if (req->cmd.buf[0] == MODE_SENSE) {
751 outbuf[0] = buflen - 1;
752 } else { /* MODE_SENSE_10 */
753 outbuf[0] = ((buflen - 2) >> 8) & 0xff;
754 outbuf[1] = (buflen - 2) & 0xff;
755 }
ebddfcbe
GH
756 if (buflen > req->cmd.xfer)
757 buflen = req->cmd.xfer;
758 return buflen;
759}
760
02880f43
GH
761static int scsi_disk_emulate_read_toc(SCSIRequest *req, uint8_t *outbuf)
762{
763 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev);
02880f43
GH
764 int start_track, format, msf, toclen;
765 uint64_t nb_sectors;
766
767 msf = req->cmd.buf[1] & 2;
768 format = req->cmd.buf[2] & 0xf;
769 start_track = req->cmd.buf[6];
428c149b 770 bdrv_get_geometry(s->bs, &nb_sectors);
02880f43
GH
771 DPRINTF("Read TOC (track %d format %d msf %d)\n", start_track, format, msf >> 1);
772 nb_sectors /= s->cluster_size;
773 switch (format) {
774 case 0:
775 toclen = cdrom_read_toc(nb_sectors, outbuf, msf, start_track);
776 break;
777 case 1:
778 /* multi session : only a single session defined */
779 toclen = 12;
780 memset(outbuf, 0, 12);
781 outbuf[1] = 0x0a;
782 outbuf[2] = 0x01;
783 outbuf[3] = 0x01;
784 break;
785 case 2:
786 toclen = cdrom_read_toc_raw(nb_sectors, outbuf, msf, start_track);
787 break;
788 default:
789 return -1;
790 }
791 if (toclen > req->cmd.xfer)
792 toclen = req->cmd.xfer;
793 return toclen;
794}
795
8af7a3ab 796static int scsi_disk_emulate_command(SCSIDiskReq *r, uint8_t *outbuf)
aa5dbdc1 797{
8af7a3ab 798 SCSIRequest *req = &r->req;
e7e25e32 799 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev);
e7e25e32 800 uint64_t nb_sectors;
aa5dbdc1 801 int buflen = 0;
78ced65e 802 int ret;
aa5dbdc1
GH
803
804 switch (req->cmd.buf[0]) {
805 case TEST_UNIT_READY:
428c149b 806 if (!bdrv_is_inserted(s->bs))
aa5dbdc1
GH
807 goto not_ready;
808 break;
51ad87c9
GH
809 case REQUEST_SENSE:
810 if (req->cmd.xfer < 4)
811 goto illegal_request;
812 memset(outbuf, 0, 4);
813 buflen = 4;
814 if (req->dev->sense.key == NOT_READY && req->cmd.xfer >= 18) {
815 memset(outbuf, 0, 18);
816 buflen = 18;
817 outbuf[7] = 10;
818 /* asc 0x3a, ascq 0: Medium not present */
819 outbuf[12] = 0x3a;
820 outbuf[13] = 0;
821 }
822 outbuf[0] = 0xf0;
823 outbuf[1] = 0;
824 outbuf[2] = req->dev->sense.key;
825 scsi_dev_clear_sense(req->dev);
826 break;
0b06c059
GH
827 case INQUIRY:
828 buflen = scsi_disk_emulate_inquiry(req, outbuf);
829 if (buflen < 0)
830 goto illegal_request;
831 break;
ebddfcbe
GH
832 case MODE_SENSE:
833 case MODE_SENSE_10:
834 buflen = scsi_disk_emulate_mode_sense(req, outbuf);
835 if (buflen < 0)
836 goto illegal_request;
837 break;
02880f43
GH
838 case READ_TOC:
839 buflen = scsi_disk_emulate_read_toc(req, outbuf);
840 if (buflen < 0)
841 goto illegal_request;
842 break;
3d53ba18
GH
843 case RESERVE:
844 if (req->cmd.buf[1] & 1)
845 goto illegal_request;
846 break;
847 case RESERVE_10:
848 if (req->cmd.buf[1] & 3)
849 goto illegal_request;
850 break;
851 case RELEASE:
852 if (req->cmd.buf[1] & 1)
853 goto illegal_request;
854 break;
855 case RELEASE_10:
856 if (req->cmd.buf[1] & 3)
857 goto illegal_request;
858 break;
8d3628ff 859 case START_STOP:
428c149b 860 if (bdrv_get_type_hint(s->bs) == BDRV_TYPE_CDROM && (req->cmd.buf[4] & 2)) {
8d3628ff 861 /* load/eject medium */
428c149b 862 bdrv_eject(s->bs, !(req->cmd.buf[4] & 1));
8d3628ff
GH
863 }
864 break;
c68b9f34 865 case ALLOW_MEDIUM_REMOVAL:
428c149b 866 bdrv_set_locked(s->bs, req->cmd.buf[4] & 1);
c68b9f34 867 break;
e7e25e32
GH
868 case READ_CAPACITY:
869 /* The normal LEN field for this command is zero. */
870 memset(outbuf, 0, 8);
428c149b 871 bdrv_get_geometry(s->bs, &nb_sectors);
e7e25e32
GH
872 if (!nb_sectors)
873 goto not_ready;
874 nb_sectors /= s->cluster_size;
875 /* Returned value is the address of the last sector. */
876 nb_sectors--;
877 /* Remember the new size for read/write sanity checking. */
878 s->max_lba = nb_sectors;
879 /* Clip to 2TB, instead of returning capacity modulo 2TB. */
880 if (nb_sectors > UINT32_MAX)
881 nb_sectors = UINT32_MAX;
882 outbuf[0] = (nb_sectors >> 24) & 0xff;
883 outbuf[1] = (nb_sectors >> 16) & 0xff;
884 outbuf[2] = (nb_sectors >> 8) & 0xff;
885 outbuf[3] = nb_sectors & 0xff;
886 outbuf[4] = 0;
887 outbuf[5] = 0;
888 outbuf[6] = s->cluster_size * 2;
889 outbuf[7] = 0;
890 buflen = 8;
891 break;
fc903943 892 case SYNCHRONIZE_CACHE:
78ced65e
KW
893 ret = bdrv_flush(s->bs);
894 if (ret < 0) {
895 if (scsi_handle_rw_error(r, -ret, SCSI_REQ_STATUS_RETRY_FLUSH)) {
896 return -1;
897 }
898 }
fc903943 899 break;
38215553
GH
900 case GET_CONFIGURATION:
901 memset(outbuf, 0, 8);
902 /* ??? This should probably return much more information. For now
903 just return the basic header indicating the CD-ROM profile. */
904 outbuf[7] = 8; // CD-ROM
905 buflen = 8;
906 break;
5dd90e2a
GH
907 case SERVICE_ACTION_IN:
908 /* Service Action In subcommands. */
909 if ((req->cmd.buf[1] & 31) == 0x10) {
910 DPRINTF("SAI READ CAPACITY(16)\n");
911 memset(outbuf, 0, req->cmd.xfer);
428c149b 912 bdrv_get_geometry(s->bs, &nb_sectors);
5dd90e2a
GH
913 if (!nb_sectors)
914 goto not_ready;
915 nb_sectors /= s->cluster_size;
916 /* Returned value is the address of the last sector. */
917 nb_sectors--;
918 /* Remember the new size for read/write sanity checking. */
919 s->max_lba = nb_sectors;
920 outbuf[0] = (nb_sectors >> 56) & 0xff;
921 outbuf[1] = (nb_sectors >> 48) & 0xff;
922 outbuf[2] = (nb_sectors >> 40) & 0xff;
923 outbuf[3] = (nb_sectors >> 32) & 0xff;
924 outbuf[4] = (nb_sectors >> 24) & 0xff;
925 outbuf[5] = (nb_sectors >> 16) & 0xff;
926 outbuf[6] = (nb_sectors >> 8) & 0xff;
927 outbuf[7] = nb_sectors & 0xff;
928 outbuf[8] = 0;
929 outbuf[9] = 0;
930 outbuf[10] = s->cluster_size * 2;
931 outbuf[11] = 0;
ee3659e3
CH
932 outbuf[12] = 0;
933 outbuf[13] = get_physical_block_exp(&s->qdev.conf);
5dd90e2a
GH
934 /* Protection, exponent and lowest lba field left blank. */
935 buflen = req->cmd.xfer;
936 break;
937 }
938 DPRINTF("Unsupported Service Action In\n");
939 goto illegal_request;
39ec9a50
GH
940 case REPORT_LUNS:
941 if (req->cmd.xfer < 16)
942 goto illegal_request;
943 memset(outbuf, 0, 16);
944 outbuf[3] = 8;
945 buflen = 16;
946 break;
88f8a5ed
GH
947 case VERIFY:
948 break;
ebef0bbb
BK
949 case REZERO_UNIT:
950 DPRINTF("Rezero Unit\n");
951 if (!bdrv_is_inserted(s->bs)) {
952 goto not_ready;
953 }
954 break;
aa5dbdc1
GH
955 default:
956 goto illegal_request;
957 }
958 scsi_req_set_status(req, GOOD, NO_SENSE);
959 return buflen;
960
961not_ready:
8af7a3ab
KW
962 scsi_command_complete(r, CHECK_CONDITION, NOT_READY);
963 return -1;
aa5dbdc1
GH
964
965illegal_request:
8af7a3ab
KW
966 scsi_command_complete(r, CHECK_CONDITION, ILLEGAL_REQUEST);
967 return -1;
aa5dbdc1
GH
968}
969
2e5d83bb
PB
970/* Execute a scsi command. Returns the length of the data expected by the
971 command. This will be Positive for data transfers from the device
972 (eg. disk reads), negative for transfers to the device (eg. disk writes),
973 and zero if the command does not transfer any data. */
974
8ccc2ace
TS
975static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
976 uint8_t *buf, int lun)
2e5d83bb 977{
d52affa7 978 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, d);
86106e59 979 uint64_t lba;
2e5d83bb
PB
980 uint32_t len;
981 int cmdlen;
982 int is_write;
a917d384
PB
983 uint8_t command;
984 uint8_t *outbuf;
4c41d2ef 985 SCSIDiskReq *r;
aa5dbdc1 986 int rc;
a917d384
PB
987
988 command = buf[0];
989 r = scsi_find_request(s, tag);
990 if (r) {
991 BADF("Tag 0x%x already in use\n", tag);
8ccc2ace 992 scsi_cancel_io(d, tag);
a917d384
PB
993 }
994 /* ??? Tags are not unique for different luns. We only implement a
995 single lun, so this should not matter. */
72aef731 996 r = scsi_new_request(s, tag, lun);
3f4cb3d3 997 outbuf = (uint8_t *)r->iov.iov_base;
2e5d83bb 998 is_write = 0;
a917d384
PB
999 DPRINTF("Command: lun=%d tag=0x%x data=0x%02x", lun, tag, buf[0]);
1000 switch (command >> 5) {
2e5d83bb 1001 case 0:
86106e59
AL
1002 lba = (uint64_t) buf[3] | ((uint64_t) buf[2] << 8) |
1003 (((uint64_t) buf[1] & 0x1f) << 16);
2e5d83bb
PB
1004 len = buf[4];
1005 cmdlen = 6;
1006 break;
1007 case 1:
1008 case 2:
86106e59
AL
1009 lba = (uint64_t) buf[5] | ((uint64_t) buf[4] << 8) |
1010 ((uint64_t) buf[3] << 16) | ((uint64_t) buf[2] << 24);
2e5d83bb
PB
1011 len = buf[8] | (buf[7] << 8);
1012 cmdlen = 10;
1013 break;
1014 case 4:
86106e59
AL
1015 lba = (uint64_t) buf[9] | ((uint64_t) buf[8] << 8) |
1016 ((uint64_t) buf[7] << 16) | ((uint64_t) buf[6] << 24) |
1017 ((uint64_t) buf[5] << 32) | ((uint64_t) buf[4] << 40) |
1018 ((uint64_t) buf[3] << 48) | ((uint64_t) buf[2] << 56);
2e5d83bb
PB
1019 len = buf[13] | (buf[12] << 8) | (buf[11] << 16) | (buf[10] << 24);
1020 cmdlen = 16;
1021 break;
1022 case 5:
86106e59
AL
1023 lba = (uint64_t) buf[5] | ((uint64_t) buf[4] << 8) |
1024 ((uint64_t) buf[3] << 16) | ((uint64_t) buf[2] << 24);
2e5d83bb
PB
1025 len = buf[9] | (buf[8] << 8) | (buf[7] << 16) | (buf[6] << 24);
1026 cmdlen = 12;
1027 break;
1028 default:
a917d384 1029 BADF("Unsupported command length, command %x\n", command);
2e5d83bb
PB
1030 goto fail;
1031 }
1032#ifdef DEBUG_SCSI
1033 {
1034 int i;
1035 for (i = 1; i < cmdlen; i++) {
1036 printf(" 0x%02x", buf[i]);
1037 }
1038 printf("\n");
1039 }
1040#endif
aa5dbdc1
GH
1041
1042 if (scsi_req_parse(&r->req, buf) != 0) {
1043 BADF("Unsupported command length, command %x\n", command);
1044 goto fail;
1045 }
1046 assert(r->req.cmd.len == cmdlen);
1047 assert(r->req.cmd.lba == lba);
1048
0fc5c15a 1049 if (lun || buf[1] >> 5) {
2e5d83bb 1050 /* Only LUN 0 supported. */
0fc5c15a 1051 DPRINTF("Unimplemented LUN %d\n", lun ? lun : buf[1] >> 5);
ebf46023 1052 if (command != REQUEST_SENSE && command != INQUIRY)
22864256 1053 goto fail;
2e5d83bb 1054 }
a917d384 1055 switch (command) {
ebf46023 1056 case TEST_UNIT_READY:
51ad87c9 1057 case REQUEST_SENSE:
0b06c059 1058 case INQUIRY:
ebddfcbe
GH
1059 case MODE_SENSE:
1060 case MODE_SENSE_10:
3d53ba18
GH
1061 case RESERVE:
1062 case RESERVE_10:
1063 case RELEASE:
1064 case RELEASE_10:
8d3628ff 1065 case START_STOP:
c68b9f34 1066 case ALLOW_MEDIUM_REMOVAL:
e7e25e32 1067 case READ_CAPACITY:
fc903943 1068 case SYNCHRONIZE_CACHE:
02880f43 1069 case READ_TOC:
38215553 1070 case GET_CONFIGURATION:
5dd90e2a 1071 case SERVICE_ACTION_IN:
39ec9a50 1072 case REPORT_LUNS:
88f8a5ed 1073 case VERIFY:
ebef0bbb 1074 case REZERO_UNIT:
8af7a3ab
KW
1075 rc = scsi_disk_emulate_command(r, outbuf);
1076 if (rc < 0) {
0b06c059 1077 return 0;
aa5dbdc1 1078 }
8af7a3ab
KW
1079
1080 r->iov.iov_len = rc;
0b06c059 1081 break;
ebf46023
GH
1082 case READ_6:
1083 case READ_10:
bd536cf3
GH
1084 case READ_12:
1085 case READ_16:
0bf9e31a 1086 DPRINTF("Read (sector %" PRId64 ", count %d)\n", lba, len);
274fb0e1
AL
1087 if (lba > s->max_lba)
1088 goto illegal_lba;
a917d384
PB
1089 r->sector = lba * s->cluster_size;
1090 r->sector_count = len * s->cluster_size;
2e5d83bb 1091 break;
ebf46023
GH
1092 case WRITE_6:
1093 case WRITE_10:
bd536cf3
GH
1094 case WRITE_12:
1095 case WRITE_16:
ebef0bbb
BK
1096 case WRITE_VERIFY:
1097 case WRITE_VERIFY_12:
1098 case WRITE_VERIFY_16:
1099 DPRINTF("Write %s(sector %" PRId64 ", count %d)\n",
1100 (command & 0xe) == 0xe ? "And Verify " : "", lba, len);
274fb0e1
AL
1101 if (lba > s->max_lba)
1102 goto illegal_lba;
a917d384
PB
1103 r->sector = lba * s->cluster_size;
1104 r->sector_count = len * s->cluster_size;
2e5d83bb
PB
1105 is_write = 1;
1106 break;
ebef0bbb
BK
1107 case MODE_SELECT:
1108 DPRINTF("Mode Select(6) (len %d)\n", len);
1109 /* We don't support mode parameter changes.
1110 Allow the mode parameter header + block descriptors only. */
1111 if (len > 12) {
1112 goto fail;
1113 }
1114 break;
1115 case MODE_SELECT_10:
1116 DPRINTF("Mode Select(10) (len %d)\n", len);
1117 /* We don't support mode parameter changes.
1118 Allow the mode parameter header + block descriptors only. */
1119 if (len > 16) {
1120 goto fail;
1121 }
1122 break;
1123 case SEEK_6:
1124 case SEEK_10:
1125 DPRINTF("Seek(%d) (sector %" PRId64 ")\n", command == SEEK_6 ? 6 : 10, lba);
1126 if (lba > s->max_lba) {
1127 goto illegal_lba;
1128 }
1129 break;
2e5d83bb
PB
1130 default:
1131 DPRINTF("Unknown SCSI command (%2.2x)\n", buf[0]);
1132 fail:
0d65e1f8 1133 scsi_command_complete(r, CHECK_CONDITION, ILLEGAL_REQUEST);
2e5d83bb 1134 return 0;
274fb0e1 1135 illegal_lba:
0d65e1f8 1136 scsi_command_complete(r, CHECK_CONDITION, HARDWARE_ERROR);
274fb0e1 1137 return 0;
2e5d83bb 1138 }
c87c0672 1139 if (r->sector_count == 0 && r->iov.iov_len == 0) {
0d65e1f8 1140 scsi_command_complete(r, GOOD, NO_SENSE);
a917d384 1141 }
c87c0672 1142 len = r->sector_count * 512 + r->iov.iov_len;
a917d384
PB
1143 if (is_write) {
1144 return -len;
1145 } else {
1146 if (!r->sector_count)
1147 r->sector_count = -1;
1148 return len;
2e5d83bb 1149 }
2e5d83bb
PB
1150}
1151
e9447f35 1152static void scsi_disk_purge_requests(SCSIDiskState *s)
56a14938 1153{
9af99d98 1154 SCSIDiskReq *r;
56a14938 1155
9af99d98
GH
1156 while (!QTAILQ_EMPTY(&s->qdev.requests)) {
1157 r = DO_UPCAST(SCSIDiskReq, req, QTAILQ_FIRST(&s->qdev.requests));
e9447f35
JK
1158 if (r->req.aiocb) {
1159 bdrv_aio_cancel(r->req.aiocb);
1160 }
9af99d98
GH
1161 scsi_remove_request(r);
1162 }
e9447f35
JK
1163}
1164
1165static void scsi_disk_reset(DeviceState *dev)
1166{
1167 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev.qdev, dev);
1168 uint64_t nb_sectors;
1169
1170 scsi_disk_purge_requests(s);
1171
1172 bdrv_get_geometry(s->bs, &nb_sectors);
1173 nb_sectors /= s->cluster_size;
1174 if (nb_sectors) {
1175 nb_sectors--;
1176 }
1177 s->max_lba = nb_sectors;
1178}
1179
1180static void scsi_destroy(SCSIDevice *dev)
1181{
1182 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
1183
1184 scsi_disk_purge_requests(s);
f8b6cc00 1185 blockdev_mark_auto_del(s->qdev.conf.bs);
56a14938
GH
1186}
1187
d52affa7 1188static int scsi_disk_initfn(SCSIDevice *dev)
2e5d83bb 1189{
d52affa7 1190 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
7d0d6950 1191 int is_cd;
f8b6cc00 1192 DriveInfo *dinfo;
2e5d83bb 1193
f8b6cc00 1194 if (!s->qdev.conf.bs) {
1ecda02b 1195 error_report("scsi-disk: drive property not set");
d52affa7
GH
1196 return -1;
1197 }
f8b6cc00 1198 s->bs = s->qdev.conf.bs;
7d0d6950 1199 is_cd = bdrv_get_type_hint(s->bs) == BDRV_TYPE_CDROM;
d52affa7 1200
98f28ad7
MA
1201 if (!is_cd && !bdrv_is_inserted(s->bs)) {
1202 error_report("Device needs media, but drive is empty");
1203 return -1;
1204 }
1205
a0fef654 1206 if (!s->serial) {
f8b6cc00
MA
1207 /* try to fall back to value set with legacy -drive serial=... */
1208 dinfo = drive_get_by_blockdev(s->bs);
1209 s->serial = qemu_strdup(*dinfo->serial ? dinfo->serial : "0");
a0fef654
MA
1210 }
1211
552fee93
MA
1212 if (!s->version) {
1213 s->version = qemu_strdup(QEMU_VERSION);
1214 }
1215
32bb404a 1216 if (bdrv_is_sg(s->bs)) {
1ecda02b 1217 error_report("scsi-disk: unwanted /dev/sg*");
32bb404a
MA
1218 return -1;
1219 }
1220
7d0d6950 1221 if (is_cd) {
8cfacf07 1222 s->qdev.blocksize = 2048;
2e5d83bb 1223 } else {
8cfacf07 1224 s->qdev.blocksize = s->qdev.conf.logical_block_size;
2e5d83bb 1225 }
8cfacf07 1226 s->cluster_size = s->qdev.blocksize / 512;
73fdb1e1 1227 s->bs->buffer_alignment = s->qdev.blocksize;
8cfacf07 1228
91376656 1229 s->qdev.type = TYPE_DISK;
ea8a5d7f 1230 qemu_add_vm_change_state_handler(scsi_dma_restart_cb, s);
7d0d6950 1231 bdrv_set_removable(s->bs, is_cd);
d52affa7
GH
1232 return 0;
1233}
1234
1235static SCSIDeviceInfo scsi_disk_info = {
1236 .qdev.name = "scsi-disk",
1237 .qdev.desc = "virtual scsi disk or cdrom",
1238 .qdev.size = sizeof(SCSIDiskState),
e9447f35 1239 .qdev.reset = scsi_disk_reset,
d52affa7 1240 .init = scsi_disk_initfn,
56a14938 1241 .destroy = scsi_destroy,
d52affa7
GH
1242 .send_command = scsi_send_command,
1243 .read_data = scsi_read_data,
1244 .write_data = scsi_write_data,
1245 .cancel_io = scsi_cancel_io,
1246 .get_buf = scsi_get_buf,
1247 .qdev.props = (Property[]) {
428c149b 1248 DEFINE_BLOCK_PROPERTIES(SCSIDiskState, qdev.conf),
383b4d9b 1249 DEFINE_PROP_STRING("ver", SCSIDiskState, version),
a0fef654 1250 DEFINE_PROP_STRING("serial", SCSIDiskState, serial),
d52affa7
GH
1251 DEFINE_PROP_END_OF_LIST(),
1252 },
1253};
1254
1255static void scsi_disk_register_devices(void)
1256{
1257 scsi_qdev_register(&scsi_disk_info);
8ccc2ace 1258}
d52affa7 1259device_init(scsi_disk_register_devices)