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