]> git.proxmox.com Git - qemu.git/blame - hw/scsi-disk.c
opencores_eth: fix RX path: FCS, padding and TL
[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
336a6915
PB
42#ifdef __linux
43#include <scsi/sg.h>
44#endif
45
f0f72ffe 46#define SCSI_DMA_BUF_SIZE 131072
57575058 47#define SCSI_MAX_INQUIRY_LEN 256
a917d384 48
d52affa7
GH
49typedef struct SCSIDiskState SCSIDiskState;
50
4c41d2ef
GH
51typedef struct SCSIDiskReq {
52 SCSIRequest req;
a917d384 53 /* Both sector and sector_count are in terms of qemu 512 byte blocks. */
e035b43d
AL
54 uint64_t sector;
55 uint32_t sector_count;
7285477a 56 uint32_t buflen;
c87c0672
AL
57 struct iovec iov;
58 QEMUIOVector qiov;
a597e79c 59 BlockAcctCookie acct;
4c41d2ef 60} SCSIDiskReq;
a917d384 61
d52affa7 62struct SCSIDiskState
a917d384 63{
d52affa7 64 SCSIDevice qdev;
419e691f 65 uint32_t removable;
8a9c16f6 66 bool media_changed;
3c2f7c12 67 bool media_event;
213189ab 68 QEMUBH *bh;
383b4d9b 69 char *version;
a0fef654 70 char *serial;
ece0d5e9 71 bool tray_open;
81b1008d 72 bool tray_locked;
2e5d83bb
PB
73};
74
71544d30 75static int scsi_handle_rw_error(SCSIDiskReq *r, int error);
5dba48a8 76
ad2d30f7 77static void scsi_free_request(SCSIRequest *req)
4d611c9a 78{
ad2d30f7
PB
79 SCSIDiskReq *r = DO_UPCAST(SCSIDiskReq, req, req);
80
7285477a
PB
81 if (r->iov.iov_base) {
82 qemu_vfree(r->iov.iov_base);
83 }
4d611c9a
PB
84}
85
b45ef674
PB
86/* Helper function for command completion with sense. */
87static void scsi_check_condition(SCSIDiskReq *r, SCSISense sense)
ed3a34a3 88{
02fa69b6
BS
89 DPRINTF("Command complete tag=0x%x sense=%d/%d/%d\n",
90 r->req.tag, sense.key, sense.asc, sense.ascq);
b45ef674
PB
91 scsi_req_build_sense(&r->req, sense);
92 scsi_req_complete(&r->req, CHECK_CONDITION);
4d611c9a
PB
93}
94
95/* Cancel a pending data transfer. */
5c6c0e51 96static void scsi_cancel_io(SCSIRequest *req)
4d611c9a 97{
5c6c0e51
HR
98 SCSIDiskReq *r = DO_UPCAST(SCSIDiskReq, req, req);
99
100 DPRINTF("Cancel tag=0x%x\n", req->tag);
101 if (r->req.aiocb) {
102 bdrv_aio_cancel(r->req.aiocb);
c7bae6a7
PB
103
104 /* This reference was left in by scsi_*_data. We take ownership of
105 * it the moment scsi_req_cancel is called, independent of whether
106 * bdrv_aio_cancel completes the request or not. */
107 scsi_req_unref(&r->req);
a917d384 108 }
5c6c0e51 109 r->req.aiocb = NULL;
a917d384
PB
110}
111
103b40f5
PB
112static uint32_t scsi_init_iovec(SCSIDiskReq *r)
113{
7285477a
PB
114 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
115
116 if (!r->iov.iov_base) {
117 r->buflen = SCSI_DMA_BUF_SIZE;
44740c38 118 r->iov.iov_base = qemu_blockalign(s->qdev.conf.bs, r->buflen);
7285477a
PB
119 }
120 r->iov.iov_len = MIN(r->sector_count * 512, r->buflen);
103b40f5
PB
121 qemu_iovec_init_external(&r->qiov, &r->iov, 1);
122 return r->qiov.size / 512;
123}
124
a917d384
PB
125static void scsi_read_complete(void * opaque, int ret)
126{
4c41d2ef 127 SCSIDiskReq *r = (SCSIDiskReq *)opaque;
a597e79c 128 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
5dba48a8 129 int n;
a917d384 130
8e321cc6
PB
131 if (r->req.aiocb != NULL) {
132 r->req.aiocb = NULL;
44740c38 133 bdrv_acct_done(s->qdev.conf.bs, &r->acct);
8e321cc6 134 }
a597e79c 135
a917d384 136 if (ret) {
71544d30 137 if (scsi_handle_rw_error(r, -ret)) {
c7bae6a7 138 goto done;
5dba48a8 139 }
4d611c9a 140 }
5dba48a8 141
103b40f5 142 DPRINTF("Data ready tag=0x%x len=%zd\n", r->req.tag, r->qiov.size);
a917d384 143
103b40f5 144 n = r->qiov.size / 512;
5dba48a8
KW
145 r->sector += n;
146 r->sector_count -= n;
103b40f5 147 scsi_req_data(&r->req, r->qiov.size);
c7bae6a7
PB
148
149done:
150 if (!r->req.io_canceled) {
151 scsi_req_unref(&r->req);
152 }
4d611c9a
PB
153}
154
0a4ac106
PB
155static void scsi_flush_complete(void * opaque, int ret)
156{
157 SCSIDiskReq *r = (SCSIDiskReq *)opaque;
158 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
159
160 if (r->req.aiocb != NULL) {
161 r->req.aiocb = NULL;
44740c38 162 bdrv_acct_done(s->qdev.conf.bs, &r->acct);
0a4ac106
PB
163 }
164
165 if (ret < 0) {
71544d30 166 if (scsi_handle_rw_error(r, -ret)) {
c7bae6a7 167 goto done;
0a4ac106
PB
168 }
169 }
170
171 scsi_req_complete(&r->req, GOOD);
c7bae6a7
PB
172
173done:
174 if (!r->req.io_canceled) {
175 scsi_req_unref(&r->req);
176 }
0a4ac106 177}
5dba48a8 178
5c6c0e51
HR
179/* Read more data from scsi device into buffer. */
180static void scsi_read_data(SCSIRequest *req)
2e5d83bb 181{
5c6c0e51 182 SCSIDiskReq *r = DO_UPCAST(SCSIDiskReq, req, req);
5dba48a8 183 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
2e5d83bb
PB
184 uint32_t n;
185
a917d384 186 if (r->sector_count == (uint32_t)-1) {
aa2b1e89 187 DPRINTF("Read buf_len=%zd\n", r->iov.iov_len);
a917d384 188 r->sector_count = 0;
ab9adc88 189 scsi_req_data(&r->req, r->iov.iov_len);
a917d384 190 return;
2e5d83bb 191 }
a917d384
PB
192 DPRINTF("Read sector_count=%d\n", r->sector_count);
193 if (r->sector_count == 0) {
b45ef674
PB
194 /* This also clears the sense buffer for REQUEST SENSE. */
195 scsi_req_complete(&r->req, GOOD);
a917d384 196 return;
2e5d83bb
PB
197 }
198
6fa2c95f
SH
199 /* No data transfer may already be in progress */
200 assert(r->req.aiocb == NULL);
201
c7bae6a7
PB
202 /* The request is used as the AIO opaque value, so add a ref. */
203 scsi_req_ref(&r->req);
efb9ee02
HR
204 if (r->req.cmd.mode == SCSI_XFER_TO_DEV) {
205 DPRINTF("Data transfer direction invalid\n");
206 scsi_read_complete(r, -EINVAL);
207 return;
208 }
209
a1aff5bf
MA
210 if (s->tray_open) {
211 scsi_read_complete(r, -ENOMEDIUM);
c7bae6a7 212 return;
a1aff5bf 213 }
c7bae6a7 214
103b40f5 215 n = scsi_init_iovec(r);
44740c38
PB
216 bdrv_acct_start(s->qdev.conf.bs, &r->acct, n * BDRV_SECTOR_SIZE, BDRV_ACCT_READ);
217 r->req.aiocb = bdrv_aio_readv(s->qdev.conf.bs, r->sector, &r->qiov, n,
c87c0672 218 scsi_read_complete, r);
d33ea50a
KW
219 if (r->req.aiocb == NULL) {
220 scsi_read_complete(r, -EIO);
221 }
2e5d83bb
PB
222}
223
c7bae6a7
PB
224/*
225 * scsi_handle_rw_error has two return values. 0 means that the error
226 * must be ignored, 1 means that the error has been processed and the
227 * caller should not do anything else for this request. Note that
228 * scsi_handle_rw_error always manages its reference counts, independent
229 * of the return value.
230 */
71544d30 231static int scsi_handle_rw_error(SCSIDiskReq *r, int error)
5dba48a8 232{
71544d30 233 int is_read = (r->req.cmd.xfer == SCSI_XFER_FROM_DEV);
4c41d2ef 234 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
44740c38 235 BlockErrorAction action = bdrv_get_on_error(s->qdev.conf.bs, is_read);
ea8a5d7f 236
380f640f 237 if (action == BLOCK_ERR_IGNORE) {
44740c38 238 bdrv_mon_event(s->qdev.conf.bs, BDRV_ACTION_IGNORE, is_read);
ea8a5d7f 239 return 0;
380f640f 240 }
ea8a5d7f
AL
241
242 if ((error == ENOSPC && action == BLOCK_ERR_STOP_ENOSPC)
243 || action == BLOCK_ERR_STOP_ANY) {
5dba48a8 244
44740c38 245 bdrv_mon_event(s->qdev.conf.bs, BDRV_ACTION_STOP, is_read);
0461d5a6 246 vm_stop(RUN_STATE_IO_ERROR);
44740c38 247 bdrv_iostatus_set_err(s->qdev.conf.bs, error);
71544d30 248 scsi_req_retry(&r->req);
ea8a5d7f 249 } else {
efb9ee02 250 switch (error) {
7e218df5
PB
251 case ENOMEDIUM:
252 scsi_check_condition(r, SENSE_CODE(NO_MEDIUM));
253 break;
efb9ee02 254 case ENOMEM:
b45ef674 255 scsi_check_condition(r, SENSE_CODE(TARGET_FAILURE));
efb9ee02
HR
256 break;
257 case EINVAL:
b45ef674 258 scsi_check_condition(r, SENSE_CODE(INVALID_FIELD));
efb9ee02
HR
259 break;
260 default:
b45ef674 261 scsi_check_condition(r, SENSE_CODE(IO_ERROR));
efb9ee02 262 break;
a1f0cce2 263 }
44740c38 264 bdrv_mon_event(s->qdev.conf.bs, BDRV_ACTION_REPORT, is_read);
ea8a5d7f 265 }
ea8a5d7f
AL
266 return 1;
267}
268
4d611c9a
PB
269static void scsi_write_complete(void * opaque, int ret)
270{
4c41d2ef 271 SCSIDiskReq *r = (SCSIDiskReq *)opaque;
a597e79c 272 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
ea8a5d7f
AL
273 uint32_t n;
274
8e321cc6
PB
275 if (r->req.aiocb != NULL) {
276 r->req.aiocb = NULL;
44740c38 277 bdrv_acct_done(s->qdev.conf.bs, &r->acct);
8e321cc6 278 }
a597e79c 279
4d611c9a 280 if (ret) {
71544d30 281 if (scsi_handle_rw_error(r, -ret)) {
c7bae6a7 282 goto done;
5dba48a8 283 }
4d611c9a
PB
284 }
285
103b40f5 286 n = r->qiov.size / 512;
ea8a5d7f
AL
287 r->sector += n;
288 r->sector_count -= n;
a917d384 289 if (r->sector_count == 0) {
b45ef674 290 scsi_req_complete(&r->req, GOOD);
a917d384 291 } else {
103b40f5
PB
292 scsi_init_iovec(r);
293 DPRINTF("Write complete tag=0x%x more=%d\n", r->req.tag, r->qiov.size);
294 scsi_req_data(&r->req, r->qiov.size);
4d611c9a 295 }
c7bae6a7
PB
296
297done:
298 if (!r->req.io_canceled) {
299 scsi_req_unref(&r->req);
300 }
4d611c9a
PB
301}
302
42741212 303static void scsi_write_data(SCSIRequest *req)
ea8a5d7f 304{
5c6c0e51 305 SCSIDiskReq *r = DO_UPCAST(SCSIDiskReq, req, req);
4c41d2ef 306 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
ea8a5d7f
AL
307 uint32_t n;
308
6fa2c95f
SH
309 /* No data transfer may already be in progress */
310 assert(r->req.aiocb == NULL);
311
c7bae6a7
PB
312 /* The request is used as the AIO opaque value, so add a ref. */
313 scsi_req_ref(&r->req);
efb9ee02
HR
314 if (r->req.cmd.mode != SCSI_XFER_TO_DEV) {
315 DPRINTF("Data transfer direction invalid\n");
316 scsi_write_complete(r, -EINVAL);
42741212 317 return;
efb9ee02
HR
318 }
319
103b40f5 320 n = r->qiov.size / 512;
ea8a5d7f 321 if (n) {
a1aff5bf
MA
322 if (s->tray_open) {
323 scsi_write_complete(r, -ENOMEDIUM);
c7bae6a7 324 return;
a1aff5bf 325 }
44740c38
PB
326 bdrv_acct_start(s->qdev.conf.bs, &r->acct, n * BDRV_SECTOR_SIZE, BDRV_ACCT_WRITE);
327 r->req.aiocb = bdrv_aio_writev(s->qdev.conf.bs, r->sector, &r->qiov, n,
103b40f5 328 scsi_write_complete, r);
d33ea50a 329 if (r->req.aiocb == NULL) {
a1f0cce2 330 scsi_write_complete(r, -ENOMEM);
d33ea50a 331 }
ea8a5d7f 332 } else {
103b40f5 333 /* Called for the first time. Ask the driver to send us more data. */
ea8a5d7f
AL
334 scsi_write_complete(r, 0);
335 }
a917d384 336}
2e5d83bb 337
a917d384 338/* Return a pointer to the data buffer. */
5c6c0e51 339static uint8_t *scsi_get_buf(SCSIRequest *req)
a917d384 340{
5c6c0e51 341 SCSIDiskReq *r = DO_UPCAST(SCSIDiskReq, req, req);
2e5d83bb 342
3f4cb3d3 343 return (uint8_t *)r->iov.iov_base;
2e5d83bb
PB
344}
345
0b06c059
GH
346static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf)
347{
383b4d9b 348 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev);
0b06c059
GH
349 int buflen = 0;
350
351 if (req->cmd.buf[1] & 0x2) {
352 /* Command support data - optional, not implemented */
353 BADF("optional INQUIRY command support request not implemented\n");
354 return -1;
355 }
356
357 if (req->cmd.buf[1] & 0x1) {
358 /* Vital product data */
359 uint8_t page_code = req->cmd.buf[2];
360 if (req->cmd.xfer < 4) {
361 BADF("Error: Inquiry (EVPD[%02X]) buffer size %zd is "
362 "less than 4\n", page_code, req->cmd.xfer);
363 return -1;
364 }
365
e39be482 366 outbuf[buflen++] = s->qdev.type & 0x1f;
0b06c059
GH
367 outbuf[buflen++] = page_code ; // this page
368 outbuf[buflen++] = 0x00;
369
370 switch (page_code) {
371 case 0x00: /* Supported page codes, mandatory */
39d98982
HR
372 {
373 int pages;
0b06c059
GH
374 DPRINTF("Inquiry EVPD[Supported pages] "
375 "buffer size %zd\n", req->cmd.xfer);
39d98982 376 pages = buflen++;
0b06c059 377 outbuf[buflen++] = 0x00; // list of supported pages (this page)
f01b5931 378 if (s->serial) {
3e1c0c9a 379 outbuf[buflen++] = 0x80; // unit serial number
f01b5931 380 }
0b06c059 381 outbuf[buflen++] = 0x83; // device identification
f37bd73b 382 if (s->qdev.type == TYPE_DISK) {
ea3bd56f
CH
383 outbuf[buflen++] = 0xb0; // block limits
384 outbuf[buflen++] = 0xb2; // thin provisioning
39d98982
HR
385 }
386 outbuf[pages] = buflen - pages - 1; // number of pages
0b06c059 387 break;
39d98982 388 }
0b06c059
GH
389 case 0x80: /* Device serial number, optional */
390 {
3e1c0c9a 391 int l;
0b06c059 392
3e1c0c9a
HR
393 if (!s->serial) {
394 DPRINTF("Inquiry (EVPD[Serial number] not supported\n");
395 return -1;
396 }
397
398 l = strlen(s->serial);
f01b5931 399 if (l > req->cmd.xfer) {
0b06c059 400 l = req->cmd.xfer;
f01b5931
PB
401 }
402 if (l > 20) {
0b06c059 403 l = 20;
f01b5931 404 }
0b06c059
GH
405
406 DPRINTF("Inquiry EVPD[Serial number] "
407 "buffer size %zd\n", req->cmd.xfer);
408 outbuf[buflen++] = l;
a0fef654 409 memcpy(outbuf+buflen, s->serial, l);
0b06c059
GH
410 buflen += l;
411 break;
412 }
413
414 case 0x83: /* Device identification page, mandatory */
415 {
416 int max_len = 255 - 8;
44740c38 417 int id_len = strlen(bdrv_get_device_name(s->qdev.conf.bs));
0b06c059 418
f01b5931 419 if (id_len > max_len) {
0b06c059 420 id_len = max_len;
f01b5931 421 }
0b06c059
GH
422 DPRINTF("Inquiry EVPD[Device identification] "
423 "buffer size %zd\n", req->cmd.xfer);
424
39d98982 425 outbuf[buflen++] = 4 + id_len;
0b06c059
GH
426 outbuf[buflen++] = 0x2; // ASCII
427 outbuf[buflen++] = 0; // not officially assigned
428 outbuf[buflen++] = 0; // reserved
429 outbuf[buflen++] = id_len; // length of data following
430
44740c38 431 memcpy(outbuf+buflen, bdrv_get_device_name(s->qdev.conf.bs), id_len);
0b06c059
GH
432 buflen += id_len;
433 break;
434 }
ea3bd56f 435 case 0xb0: /* block limits */
ee3659e3 436 {
ea3bd56f
CH
437 unsigned int unmap_sectors =
438 s->qdev.conf.discard_granularity / s->qdev.blocksize;
8cfacf07
CH
439 unsigned int min_io_size =
440 s->qdev.conf.min_io_size / s->qdev.blocksize;
441 unsigned int opt_io_size =
442 s->qdev.conf.opt_io_size / s->qdev.blocksize;
ee3659e3 443
f37bd73b 444 if (s->qdev.type == TYPE_ROM) {
39d98982
HR
445 DPRINTF("Inquiry (EVPD[%02X] not supported for CDROM\n",
446 page_code);
447 return -1;
448 }
ee3659e3
CH
449 /* required VPD size with unmap support */
450 outbuf[3] = buflen = 0x3c;
451
452 memset(outbuf + 4, 0, buflen - 4);
453
454 /* optimal transfer length granularity */
455 outbuf[6] = (min_io_size >> 8) & 0xff;
456 outbuf[7] = min_io_size & 0xff;
457
458 /* optimal transfer length */
459 outbuf[12] = (opt_io_size >> 24) & 0xff;
460 outbuf[13] = (opt_io_size >> 16) & 0xff;
461 outbuf[14] = (opt_io_size >> 8) & 0xff;
462 outbuf[15] = opt_io_size & 0xff;
ea3bd56f
CH
463
464 /* optimal unmap granularity */
465 outbuf[28] = (unmap_sectors >> 24) & 0xff;
466 outbuf[29] = (unmap_sectors >> 16) & 0xff;
467 outbuf[30] = (unmap_sectors >> 8) & 0xff;
468 outbuf[31] = unmap_sectors & 0xff;
469 break;
470 }
471 case 0xb2: /* thin provisioning */
472 {
473 outbuf[3] = buflen = 8;
474 outbuf[4] = 0;
475 outbuf[5] = 0x40; /* write same with unmap supported */
476 outbuf[6] = 0;
477 outbuf[7] = 0;
ee3659e3
CH
478 break;
479 }
0b06c059
GH
480 default:
481 BADF("Error: unsupported Inquiry (EVPD[%02X]) "
482 "buffer size %zd\n", page_code, req->cmd.xfer);
483 return -1;
484 }
485 /* done with EVPD */
486 return buflen;
487 }
488
489 /* Standard INQUIRY data */
490 if (req->cmd.buf[2] != 0) {
491 BADF("Error: Inquiry (STANDARD) page or code "
492 "is non-zero [%02X]\n", req->cmd.buf[2]);
493 return -1;
494 }
495
496 /* PAGE CODE == 0 */
497 if (req->cmd.xfer < 5) {
498 BADF("Error: Inquiry (STANDARD) buffer size %zd "
499 "is less than 5\n", req->cmd.xfer);
500 return -1;
501 }
502
0b06c059 503 buflen = req->cmd.xfer;
f01b5931 504 if (buflen > SCSI_MAX_INQUIRY_LEN) {
0b06c059 505 buflen = SCSI_MAX_INQUIRY_LEN;
f01b5931 506 }
0b06c059
GH
507 memset(outbuf, 0, buflen);
508
f37bd73b 509 outbuf[0] = s->qdev.type & 0x1f;
e39be482 510 outbuf[1] = s->removable ? 0x80 : 0;
f37bd73b 511 if (s->qdev.type == TYPE_ROM) {
550fe6c6 512 memcpy(&outbuf[16], "QEMU CD-ROM ", 16);
0b06c059 513 } else {
550fe6c6 514 memcpy(&outbuf[16], "QEMU HARDDISK ", 16);
0b06c059 515 }
550fe6c6 516 memcpy(&outbuf[8], "QEMU ", 8);
314b1811 517 memset(&outbuf[32], 0, 4);
552fee93 518 memcpy(&outbuf[32], s->version, MIN(4, strlen(s->version)));
99aba0c4
CH
519 /*
520 * We claim conformance to SPC-3, which is required for guests
521 * to ask for modern features like READ CAPACITY(16) or the
522 * block characteristics VPD page by default. Not all of SPC-3
523 * is actually implemented, but we're good enough.
524 */
ee3659e3 525 outbuf[2] = 5;
0b06c059 526 outbuf[3] = 2; /* Format 2 */
ad3cea42
AT
527
528 if (buflen > 36) {
529 outbuf[4] = buflen - 5; /* Additional Length = (Len - 1) - 4 */
530 } else {
531 /* If the allocation length of CDB is too small,
532 the additional length is not adjusted */
533 outbuf[4] = 36 - 5;
534 }
535
0b06c059 536 /* Sync data transfer and TCQ. */
afd4030c 537 outbuf[7] = 0x10 | (req->bus->info->tcq ? 0x02 : 0);
0b06c059
GH
538 return buflen;
539}
540
430ee2f2
PB
541static inline bool media_is_dvd(SCSIDiskState *s)
542{
543 uint64_t nb_sectors;
544 if (s->qdev.type != TYPE_ROM) {
545 return false;
546 }
44740c38 547 if (!bdrv_is_inserted(s->qdev.conf.bs)) {
430ee2f2
PB
548 return false;
549 }
44740c38 550 bdrv_get_geometry(s->qdev.conf.bs, &nb_sectors);
430ee2f2
PB
551 return nb_sectors > CD_MAX_SECTORS;
552}
553
ceb792ef
PB
554static inline bool media_is_cd(SCSIDiskState *s)
555{
556 uint64_t nb_sectors;
557 if (s->qdev.type != TYPE_ROM) {
558 return false;
559 }
44740c38 560 if (!bdrv_is_inserted(s->qdev.conf.bs)) {
ceb792ef
PB
561 return false;
562 }
44740c38 563 bdrv_get_geometry(s->qdev.conf.bs, &nb_sectors);
ceb792ef
PB
564 return nb_sectors <= CD_MAX_SECTORS;
565}
566
b6c251ab
PB
567static int scsi_read_dvd_structure(SCSIDiskState *s, SCSIDiskReq *r,
568 uint8_t *outbuf)
569{
ceb792ef
PB
570 static const int rds_caps_size[5] = {
571 [0] = 2048 + 4,
572 [1] = 4 + 4,
573 [3] = 188 + 4,
574 [4] = 2048 + 4,
575 };
576
577 uint8_t media = r->req.cmd.buf[1];
578 uint8_t layer = r->req.cmd.buf[6];
579 uint8_t format = r->req.cmd.buf[7];
580 int size = -1;
581
582 if (s->qdev.type != TYPE_ROM) {
583 return -1;
584 }
585 if (media != 0) {
586 scsi_check_condition(r, SENSE_CODE(INVALID_FIELD));
587 return -1;
588 }
589
590 if (format != 0xff) {
44740c38 591 if (s->tray_open || !bdrv_is_inserted(s->qdev.conf.bs)) {
ceb792ef
PB
592 scsi_check_condition(r, SENSE_CODE(NO_MEDIUM));
593 return -1;
594 }
595 if (media_is_cd(s)) {
596 scsi_check_condition(r, SENSE_CODE(INCOMPATIBLE_FORMAT));
597 return -1;
598 }
599 if (format >= ARRAY_SIZE(rds_caps_size)) {
600 return -1;
601 }
602 size = rds_caps_size[format];
603 memset(outbuf, 0, size);
604 }
605
606 switch (format) {
607 case 0x00: {
608 /* Physical format information */
609 uint64_t nb_sectors;
610 if (layer != 0) {
611 goto fail;
612 }
44740c38 613 bdrv_get_geometry(s->qdev.conf.bs, &nb_sectors);
ceb792ef
PB
614
615 outbuf[4] = 1; /* DVD-ROM, part version 1 */
616 outbuf[5] = 0xf; /* 120mm disc, minimum rate unspecified */
617 outbuf[6] = 1; /* one layer, read-only (per MMC-2 spec) */
618 outbuf[7] = 0; /* default densities */
619
620 stl_be_p(&outbuf[12], (nb_sectors >> 2) - 1); /* end sector */
621 stl_be_p(&outbuf[16], (nb_sectors >> 2) - 1); /* l0 end sector */
622 break;
623 }
624
625 case 0x01: /* DVD copyright information, all zeros */
626 break;
627
628 case 0x03: /* BCA information - invalid field for no BCA info */
629 return -1;
630
631 case 0x04: /* DVD disc manufacturing information, all zeros */
632 break;
633
634 case 0xff: { /* List capabilities */
635 int i;
636 size = 4;
637 for (i = 0; i < ARRAY_SIZE(rds_caps_size); i++) {
638 if (!rds_caps_size[i]) {
639 continue;
640 }
641 outbuf[size] = i;
642 outbuf[size + 1] = 0x40; /* Not writable, readable */
643 stw_be_p(&outbuf[size + 2], rds_caps_size[i]);
644 size += 4;
645 }
646 break;
647 }
648
649 default:
650 return -1;
651 }
652
653 /* Size of buffer, not including 2 byte size field */
654 stw_be_p(outbuf, size - 2);
655 return size;
656
657fail:
b6c251ab
PB
658 return -1;
659}
660
3c2f7c12 661static int scsi_event_status_media(SCSIDiskState *s, uint8_t *outbuf)
b6c251ab 662{
3c2f7c12
PB
663 uint8_t event_code, media_status;
664
665 media_status = 0;
666 if (s->tray_open) {
667 media_status = MS_TRAY_OPEN;
44740c38 668 } else if (bdrv_is_inserted(s->qdev.conf.bs)) {
3c2f7c12
PB
669 media_status = MS_MEDIA_PRESENT;
670 }
671
672 /* Event notification descriptor */
673 event_code = MEC_NO_CHANGE;
674 if (media_status != MS_TRAY_OPEN && s->media_event) {
675 event_code = MEC_NEW_MEDIA;
676 s->media_event = false;
677 }
678
679 outbuf[0] = event_code;
680 outbuf[1] = media_status;
681
682 /* These fields are reserved, just clear them. */
683 outbuf[2] = 0;
684 outbuf[3] = 0;
685 return 4;
686}
687
688static int scsi_get_event_status_notification(SCSIDiskState *s, SCSIDiskReq *r,
689 uint8_t *outbuf)
690{
691 int size;
692 uint8_t *buf = r->req.cmd.buf;
693 uint8_t notification_class_request = buf[4];
694 if (s->qdev.type != TYPE_ROM) {
695 return -1;
696 }
697 if ((buf[1] & 1) == 0) {
698 /* asynchronous */
699 return -1;
700 }
701
702 size = 4;
703 outbuf[0] = outbuf[1] = 0;
704 outbuf[3] = 1 << GESN_MEDIA; /* supported events */
705 if (notification_class_request & (1 << GESN_MEDIA)) {
706 outbuf[2] = GESN_MEDIA;
707 size += scsi_event_status_media(s, &outbuf[size]);
708 } else {
709 outbuf[2] = 0x80;
710 }
711 stw_be_p(outbuf, size - 4);
712 return size;
b6c251ab
PB
713}
714
430ee2f2 715static int scsi_get_configuration(SCSIDiskState *s, uint8_t *outbuf)
b6c251ab 716{
430ee2f2
PB
717 int current;
718
b6c251ab
PB
719 if (s->qdev.type != TYPE_ROM) {
720 return -1;
721 }
430ee2f2
PB
722 current = media_is_dvd(s) ? MMC_PROFILE_DVD_ROM : MMC_PROFILE_CD_ROM;
723 memset(outbuf, 0, 40);
724 stl_be_p(&outbuf[0], 36); /* Bytes after the data length field */
725 stw_be_p(&outbuf[6], current);
726 /* outbuf[8] - outbuf[19]: Feature 0 - Profile list */
727 outbuf[10] = 0x03; /* persistent, current */
728 outbuf[11] = 8; /* two profiles */
729 stw_be_p(&outbuf[12], MMC_PROFILE_DVD_ROM);
730 outbuf[14] = (current == MMC_PROFILE_DVD_ROM);
731 stw_be_p(&outbuf[16], MMC_PROFILE_CD_ROM);
732 outbuf[18] = (current == MMC_PROFILE_CD_ROM);
733 /* outbuf[20] - outbuf[31]: Feature 1 - Core feature */
734 stw_be_p(&outbuf[20], 1);
735 outbuf[22] = 0x08 | 0x03; /* version 2, persistent, current */
736 outbuf[23] = 8;
737 stl_be_p(&outbuf[24], 1); /* SCSI */
738 outbuf[28] = 1; /* DBE = 1, mandatory */
739 /* outbuf[32] - outbuf[39]: Feature 3 - Removable media feature */
740 stw_be_p(&outbuf[32], 3);
741 outbuf[34] = 0x08 | 0x03; /* version 2, persistent, current */
742 outbuf[35] = 4;
743 outbuf[36] = 0x39; /* tray, load=1, eject=1, unlocked at powerup, lock=1 */
744 /* TODO: Random readable, CD read, DVD read, drive serial number,
745 power management */
746 return 40;
b6c251ab
PB
747}
748
749static int scsi_emulate_mechanism_status(SCSIDiskState *s, uint8_t *outbuf)
750{
751 if (s->qdev.type != TYPE_ROM) {
752 return -1;
753 }
754 memset(outbuf, 0, 8);
755 outbuf[5] = 1; /* CD-ROM */
756 return 8;
757}
758
cfc606da 759static int mode_sense_page(SCSIDiskState *s, int page, uint8_t **p_outbuf,
282ab04e 760 int page_control)
ebddfcbe 761{
a8f4bbe2
PB
762 static const int mode_sense_valid[0x3f] = {
763 [MODE_PAGE_HD_GEOMETRY] = (1 << TYPE_DISK),
764 [MODE_PAGE_FLEXIBLE_DISK_GEOMETRY] = (1 << TYPE_DISK),
765 [MODE_PAGE_CACHING] = (1 << TYPE_DISK) | (1 << TYPE_ROM),
a07c7dcd
PB
766 [MODE_PAGE_R_W_ERROR] = (1 << TYPE_DISK) | (1 << TYPE_ROM),
767 [MODE_PAGE_AUDIO_CTL] = (1 << TYPE_ROM),
a8f4bbe2
PB
768 [MODE_PAGE_CAPABILITIES] = (1 << TYPE_ROM),
769 };
770
44740c38 771 BlockDriverState *bdrv = s->qdev.conf.bs;
ebddfcbe 772 int cylinders, heads, secs;
cfc606da 773 uint8_t *p = *p_outbuf;
ebddfcbe 774
a8f4bbe2
PB
775 if ((mode_sense_valid[page] & (1 << s->qdev.type)) == 0) {
776 return -1;
777 }
778
779 p[0] = page;
780
282ab04e
BK
781 /*
782 * If Changeable Values are requested, a mask denoting those mode parameters
783 * that are changeable shall be returned. As we currently don't support
784 * parameter changes via MODE_SELECT all bits are returned set to zero.
785 * The buffer was already menset to zero by the caller of this function.
786 */
ebddfcbe 787 switch (page) {
67cc61e4 788 case MODE_PAGE_HD_GEOMETRY:
ebddfcbe 789 p[1] = 0x16;
282ab04e 790 if (page_control == 1) { /* Changeable Values */
cfc606da 791 break;
282ab04e 792 }
ebddfcbe
GH
793 /* if a geometry hint is available, use it */
794 bdrv_get_geometry_hint(bdrv, &cylinders, &heads, &secs);
795 p[2] = (cylinders >> 16) & 0xff;
796 p[3] = (cylinders >> 8) & 0xff;
797 p[4] = cylinders & 0xff;
798 p[5] = heads & 0xff;
799 /* Write precomp start cylinder, disabled */
800 p[6] = (cylinders >> 16) & 0xff;
801 p[7] = (cylinders >> 8) & 0xff;
802 p[8] = cylinders & 0xff;
803 /* Reduced current start cylinder, disabled */
804 p[9] = (cylinders >> 16) & 0xff;
805 p[10] = (cylinders >> 8) & 0xff;
806 p[11] = cylinders & 0xff;
807 /* Device step rate [ns], 200ns */
808 p[12] = 0;
809 p[13] = 200;
810 /* Landing zone cylinder */
811 p[14] = 0xff;
812 p[15] = 0xff;
813 p[16] = 0xff;
814 /* Medium rotation rate [rpm], 5400 rpm */
815 p[20] = (5400 >> 8) & 0xff;
816 p[21] = 5400 & 0xff;
cfc606da 817 break;
ebddfcbe 818
67cc61e4 819 case MODE_PAGE_FLEXIBLE_DISK_GEOMETRY:
ebddfcbe 820 p[1] = 0x1e;
282ab04e 821 if (page_control == 1) { /* Changeable Values */
cfc606da 822 break;
282ab04e 823 }
ebddfcbe
GH
824 /* Transfer rate [kbit/s], 5Mbit/s */
825 p[2] = 5000 >> 8;
826 p[3] = 5000 & 0xff;
827 /* if a geometry hint is available, use it */
828 bdrv_get_geometry_hint(bdrv, &cylinders, &heads, &secs);
829 p[4] = heads & 0xff;
830 p[5] = secs & 0xff;
69377307 831 p[6] = s->qdev.blocksize >> 8;
ebddfcbe
GH
832 p[8] = (cylinders >> 8) & 0xff;
833 p[9] = cylinders & 0xff;
834 /* Write precomp start cylinder, disabled */
835 p[10] = (cylinders >> 8) & 0xff;
836 p[11] = cylinders & 0xff;
837 /* Reduced current start cylinder, disabled */
838 p[12] = (cylinders >> 8) & 0xff;
839 p[13] = cylinders & 0xff;
840 /* Device step rate [100us], 100us */
841 p[14] = 0;
842 p[15] = 1;
843 /* Device step pulse width [us], 1us */
844 p[16] = 1;
845 /* Device head settle delay [100us], 100us */
846 p[17] = 0;
847 p[18] = 1;
848 /* Motor on delay [0.1s], 0.1s */
849 p[19] = 1;
850 /* Motor off delay [0.1s], 0.1s */
851 p[20] = 1;
852 /* Medium rotation rate [rpm], 5400 rpm */
853 p[28] = (5400 >> 8) & 0xff;
854 p[29] = 5400 & 0xff;
cfc606da 855 break;
ebddfcbe 856
67cc61e4 857 case MODE_PAGE_CACHING:
ebddfcbe
GH
858 p[0] = 8;
859 p[1] = 0x12;
282ab04e 860 if (page_control == 1) { /* Changeable Values */
cfc606da 861 break;
282ab04e 862 }
44740c38 863 if (bdrv_enable_write_cache(s->qdev.conf.bs)) {
ebddfcbe
GH
864 p[2] = 4; /* WCE */
865 }
cfc606da 866 break;
ebddfcbe 867
a07c7dcd
PB
868 case MODE_PAGE_R_W_ERROR:
869 p[1] = 10;
870 p[2] = 0x80; /* Automatic Write Reallocation Enabled */
871 if (s->qdev.type == TYPE_ROM) {
872 p[3] = 0x20; /* Read Retry Count */
873 }
874 break;
875
876 case MODE_PAGE_AUDIO_CTL:
877 p[1] = 14;
878 break;
879
67cc61e4 880 case MODE_PAGE_CAPABILITIES:
ebddfcbe 881 p[1] = 0x14;
282ab04e 882 if (page_control == 1) { /* Changeable Values */
cfc606da 883 break;
282ab04e 884 }
a07c7dcd
PB
885
886 p[2] = 0x3b; /* CD-R & CD-RW read */
887 p[3] = 0; /* Writing not supported */
ebddfcbe
GH
888 p[4] = 0x7f; /* Audio, composite, digital out,
889 mode 2 form 1&2, multi session */
890 p[5] = 0xff; /* CD DA, DA accurate, RW supported,
891 RW corrected, C2 errors, ISRC,
892 UPC, Bar code */
81b1008d 893 p[6] = 0x2d | (s->tray_locked ? 2 : 0);
ebddfcbe
GH
894 /* Locking supported, jumper present, eject, tray */
895 p[7] = 0; /* no volume & mute control, no
896 changer */
a07c7dcd 897 p[8] = (50 * 176) >> 8; /* 50x read speed */
ebddfcbe 898 p[9] = (50 * 176) & 0xff;
a07c7dcd
PB
899 p[10] = 2 >> 8; /* Two volume levels */
900 p[11] = 2 & 0xff;
901 p[12] = 2048 >> 8; /* 2M buffer */
ebddfcbe 902 p[13] = 2048 & 0xff;
a07c7dcd 903 p[14] = (16 * 176) >> 8; /* 16x read speed current */
ebddfcbe 904 p[15] = (16 * 176) & 0xff;
a07c7dcd 905 p[18] = (16 * 176) >> 8; /* 16x write speed */
ebddfcbe 906 p[19] = (16 * 176) & 0xff;
a07c7dcd 907 p[20] = (16 * 176) >> 8; /* 16x write speed current */
ebddfcbe 908 p[21] = (16 * 176) & 0xff;
cfc606da 909 break;
ebddfcbe
GH
910
911 default:
cfc606da 912 return -1;
ebddfcbe 913 }
cfc606da
PB
914
915 *p_outbuf += p[1] + 2;
916 return p[1] + 2;
ebddfcbe
GH
917}
918
cfc606da 919static int scsi_disk_emulate_mode_sense(SCSIDiskReq *r, uint8_t *outbuf)
ebddfcbe 920{
cfc606da 921 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
ebddfcbe 922 uint64_t nb_sectors;
cfc606da 923 int page, dbd, buflen, ret, page_control;
ebddfcbe 924 uint8_t *p;
ce512ee1 925 uint8_t dev_specific_param;
ebddfcbe 926
cfc606da
PB
927 dbd = r->req.cmd.buf[1] & 0x8;
928 page = r->req.cmd.buf[2] & 0x3f;
929 page_control = (r->req.cmd.buf[2] & 0xc0) >> 6;
aa2b1e89 930 DPRINTF("Mode Sense(%d) (page %d, xfer %zd, page_control %d)\n",
cfc606da
PB
931 (r->req.cmd.buf[0] == MODE_SENSE) ? 6 : 10, page, r->req.cmd.xfer, page_control);
932 memset(outbuf, 0, r->req.cmd.xfer);
ebddfcbe
GH
933 p = outbuf;
934
44740c38 935 if (bdrv_is_read_only(s->qdev.conf.bs)) {
ce512ee1
BK
936 dev_specific_param = 0x80; /* Readonly. */
937 } else {
938 dev_specific_param = 0x00;
939 }
940
cfc606da 941 if (r->req.cmd.buf[0] == MODE_SENSE) {
ce512ee1
BK
942 p[1] = 0; /* Default media type. */
943 p[2] = dev_specific_param;
944 p[3] = 0; /* Block descriptor length. */
945 p += 4;
946 } else { /* MODE_SENSE_10 */
947 p[2] = 0; /* Default media type. */
948 p[3] = dev_specific_param;
949 p[6] = p[7] = 0; /* Block descriptor length. */
950 p += 8;
ebddfcbe 951 }
ebddfcbe 952
44740c38 953 bdrv_get_geometry(s->qdev.conf.bs, &nb_sectors);
333d50fe 954 if (!dbd && nb_sectors) {
cfc606da 955 if (r->req.cmd.buf[0] == MODE_SENSE) {
ce512ee1
BK
956 outbuf[3] = 8; /* Block descriptor length */
957 } else { /* MODE_SENSE_10 */
958 outbuf[7] = 8; /* Block descriptor length */
959 }
69377307 960 nb_sectors /= (s->qdev.blocksize / 512);
f01b5931 961 if (nb_sectors > 0xffffff) {
2488b740 962 nb_sectors = 0;
f01b5931 963 }
ebddfcbe
GH
964 p[0] = 0; /* media density code */
965 p[1] = (nb_sectors >> 16) & 0xff;
966 p[2] = (nb_sectors >> 8) & 0xff;
967 p[3] = nb_sectors & 0xff;
968 p[4] = 0; /* reserved */
969 p[5] = 0; /* bytes 5-7 are the sector size in bytes */
69377307 970 p[6] = s->qdev.blocksize >> 8;
ebddfcbe
GH
971 p[7] = 0;
972 p += 8;
973 }
974
cfc606da
PB
975 if (page_control == 3) {
976 /* Saved Values */
977 scsi_check_condition(r, SENSE_CODE(SAVING_PARAMS_NOT_SUPPORTED));
978 return -1;
282ab04e
BK
979 }
980
cfc606da
PB
981 if (page == 0x3f) {
982 for (page = 0; page <= 0x3e; page++) {
983 mode_sense_page(s, page, &p, page_control);
984 }
985 } else {
986 ret = mode_sense_page(s, page, &p, page_control);
987 if (ret == -1) {
988 return -1;
989 }
ebddfcbe
GH
990 }
991
992 buflen = p - outbuf;
ce512ee1
BK
993 /*
994 * The mode data length field specifies the length in bytes of the
995 * following data that is available to be transferred. The mode data
996 * length does not include itself.
997 */
cfc606da 998 if (r->req.cmd.buf[0] == MODE_SENSE) {
ce512ee1
BK
999 outbuf[0] = buflen - 1;
1000 } else { /* MODE_SENSE_10 */
1001 outbuf[0] = ((buflen - 2) >> 8) & 0xff;
1002 outbuf[1] = (buflen - 2) & 0xff;
1003 }
f01b5931 1004 if (buflen > r->req.cmd.xfer) {
cfc606da 1005 buflen = r->req.cmd.xfer;
f01b5931 1006 }
ebddfcbe
GH
1007 return buflen;
1008}
1009
02880f43
GH
1010static int scsi_disk_emulate_read_toc(SCSIRequest *req, uint8_t *outbuf)
1011{
1012 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev);
02880f43
GH
1013 int start_track, format, msf, toclen;
1014 uint64_t nb_sectors;
1015
1016 msf = req->cmd.buf[1] & 2;
1017 format = req->cmd.buf[2] & 0xf;
1018 start_track = req->cmd.buf[6];
44740c38 1019 bdrv_get_geometry(s->qdev.conf.bs, &nb_sectors);
02880f43 1020 DPRINTF("Read TOC (track %d format %d msf %d)\n", start_track, format, msf >> 1);
69377307 1021 nb_sectors /= s->qdev.blocksize / 512;
02880f43
GH
1022 switch (format) {
1023 case 0:
1024 toclen = cdrom_read_toc(nb_sectors, outbuf, msf, start_track);
1025 break;
1026 case 1:
1027 /* multi session : only a single session defined */
1028 toclen = 12;
1029 memset(outbuf, 0, 12);
1030 outbuf[1] = 0x0a;
1031 outbuf[2] = 0x01;
1032 outbuf[3] = 0x01;
1033 break;
1034 case 2:
1035 toclen = cdrom_read_toc_raw(nb_sectors, outbuf, msf, start_track);
1036 break;
1037 default:
1038 return -1;
1039 }
f01b5931 1040 if (toclen > req->cmd.xfer) {
02880f43 1041 toclen = req->cmd.xfer;
f01b5931 1042 }
02880f43
GH
1043 return toclen;
1044}
1045
68bb01f3 1046static int scsi_disk_emulate_start_stop(SCSIDiskReq *r)
bfd52647
MA
1047{
1048 SCSIRequest *req = &r->req;
1049 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev);
1050 bool start = req->cmd.buf[4] & 1;
1051 bool loej = req->cmd.buf[4] & 2; /* load on start, eject on !start */
1052
1053 if (s->qdev.type == TYPE_ROM && loej) {
68bb01f3
MA
1054 if (!start && !s->tray_open && s->tray_locked) {
1055 scsi_check_condition(r,
44740c38 1056 bdrv_is_inserted(s->qdev.conf.bs)
68bb01f3
MA
1057 ? SENSE_CODE(ILLEGAL_REQ_REMOVAL_PREVENTED)
1058 : SENSE_CODE(NOT_READY_REMOVAL_PREVENTED));
1059 return -1;
fdec4404 1060 }
44740c38 1061 bdrv_eject(s->qdev.conf.bs, !start);
ece0d5e9 1062 s->tray_open = !start;
bfd52647 1063 }
68bb01f3 1064 return 0;
bfd52647
MA
1065}
1066
7285477a 1067static int scsi_disk_emulate_command(SCSIDiskReq *r)
aa5dbdc1 1068{
8af7a3ab 1069 SCSIRequest *req = &r->req;
e7e25e32 1070 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev);
e7e25e32 1071 uint64_t nb_sectors;
7285477a 1072 uint8_t *outbuf;
aa5dbdc1
GH
1073 int buflen = 0;
1074
7285477a
PB
1075 if (!r->iov.iov_base) {
1076 /*
1077 * FIXME: we shouldn't return anything bigger than 4k, but the code
1078 * requires the buffer to be as big as req->cmd.xfer in several
1079 * places. So, do not allow CDBs with a very large ALLOCATION
1080 * LENGTH. The real fix would be to modify scsi_read_data and
1081 * dma_buf_read, so that they return data beyond the buflen
1082 * as all zeros.
1083 */
1084 if (req->cmd.xfer > 65536) {
1085 goto illegal_request;
1086 }
1087 r->buflen = MAX(4096, req->cmd.xfer);
44740c38 1088 r->iov.iov_base = qemu_blockalign(s->qdev.conf.bs, r->buflen);
7285477a
PB
1089 }
1090
1091 outbuf = r->iov.iov_base;
aa5dbdc1
GH
1092 switch (req->cmd.buf[0]) {
1093 case TEST_UNIT_READY:
44740c38 1094 if (s->tray_open || !bdrv_is_inserted(s->qdev.conf.bs)) {
aa5dbdc1 1095 goto not_ready;
f01b5931 1096 }
5f71d32f 1097 break;
0b06c059
GH
1098 case INQUIRY:
1099 buflen = scsi_disk_emulate_inquiry(req, outbuf);
f01b5931 1100 if (buflen < 0) {
0b06c059 1101 goto illegal_request;
f01b5931 1102 }
5f71d32f 1103 break;
ebddfcbe
GH
1104 case MODE_SENSE:
1105 case MODE_SENSE_10:
cfc606da 1106 buflen = scsi_disk_emulate_mode_sense(r, outbuf);
f01b5931 1107 if (buflen < 0) {
ebddfcbe 1108 goto illegal_request;
f01b5931 1109 }
ebddfcbe 1110 break;
02880f43
GH
1111 case READ_TOC:
1112 buflen = scsi_disk_emulate_read_toc(req, outbuf);
f01b5931 1113 if (buflen < 0) {
02880f43 1114 goto illegal_request;
f01b5931 1115 }
02880f43 1116 break;
3d53ba18 1117 case RESERVE:
f01b5931 1118 if (req->cmd.buf[1] & 1) {
3d53ba18 1119 goto illegal_request;
f01b5931 1120 }
3d53ba18
GH
1121 break;
1122 case RESERVE_10:
f01b5931 1123 if (req->cmd.buf[1] & 3) {
3d53ba18 1124 goto illegal_request;
f01b5931 1125 }
3d53ba18
GH
1126 break;
1127 case RELEASE:
f01b5931 1128 if (req->cmd.buf[1] & 1) {
3d53ba18 1129 goto illegal_request;
f01b5931 1130 }
3d53ba18
GH
1131 break;
1132 case RELEASE_10:
f01b5931 1133 if (req->cmd.buf[1] & 3) {
3d53ba18 1134 goto illegal_request;
f01b5931 1135 }
3d53ba18 1136 break;
8d3628ff 1137 case START_STOP:
68bb01f3
MA
1138 if (scsi_disk_emulate_start_stop(r) < 0) {
1139 return -1;
1140 }
5f71d32f 1141 break;
c68b9f34 1142 case ALLOW_MEDIUM_REMOVAL:
81b1008d 1143 s->tray_locked = req->cmd.buf[4] & 1;
44740c38 1144 bdrv_lock_medium(s->qdev.conf.bs, req->cmd.buf[4] & 1);
5f71d32f 1145 break;
5e30a07d 1146 case READ_CAPACITY_10:
e7e25e32 1147 /* The normal LEN field for this command is zero. */
5f71d32f 1148 memset(outbuf, 0, 8);
44740c38 1149 bdrv_get_geometry(s->qdev.conf.bs, &nb_sectors);
f01b5931 1150 if (!nb_sectors) {
e7e25e32 1151 goto not_ready;
f01b5931 1152 }
7cec78b6
PB
1153 if ((req->cmd.buf[8] & 1) == 0 && req->cmd.lba) {
1154 goto illegal_request;
1155 }
69377307 1156 nb_sectors /= s->qdev.blocksize / 512;
e7e25e32
GH
1157 /* Returned value is the address of the last sector. */
1158 nb_sectors--;
1159 /* Remember the new size for read/write sanity checking. */
7877903a 1160 s->qdev.max_lba = nb_sectors;
e7e25e32 1161 /* Clip to 2TB, instead of returning capacity modulo 2TB. */
f01b5931 1162 if (nb_sectors > UINT32_MAX) {
e7e25e32 1163 nb_sectors = UINT32_MAX;
f01b5931 1164 }
e7e25e32
GH
1165 outbuf[0] = (nb_sectors >> 24) & 0xff;
1166 outbuf[1] = (nb_sectors >> 16) & 0xff;
1167 outbuf[2] = (nb_sectors >> 8) & 0xff;
1168 outbuf[3] = nb_sectors & 0xff;
1169 outbuf[4] = 0;
1170 outbuf[5] = 0;
69377307 1171 outbuf[6] = s->qdev.blocksize >> 8;
e7e25e32
GH
1172 outbuf[7] = 0;
1173 buflen = 8;
5f71d32f 1174 break;
b6c251ab
PB
1175 case MECHANISM_STATUS:
1176 buflen = scsi_emulate_mechanism_status(s, outbuf);
1177 if (buflen < 0) {
1178 goto illegal_request;
1179 }
1180 break;
38215553 1181 case GET_CONFIGURATION:
430ee2f2 1182 buflen = scsi_get_configuration(s, outbuf);
b6c251ab
PB
1183 if (buflen < 0) {
1184 goto illegal_request;
1185 }
1186 break;
1187 case GET_EVENT_STATUS_NOTIFICATION:
1188 buflen = scsi_get_event_status_notification(s, r, outbuf);
1189 if (buflen < 0) {
1190 goto illegal_request;
1191 }
1192 break;
1193 case READ_DVD_STRUCTURE:
1194 buflen = scsi_read_dvd_structure(s, r, outbuf);
1195 if (buflen < 0) {
1196 goto illegal_request;
1197 }
38215553 1198 break;
f6515262 1199 case SERVICE_ACTION_IN_16:
5dd90e2a 1200 /* Service Action In subcommands. */
f6515262 1201 if ((req->cmd.buf[1] & 31) == SAI_READ_CAPACITY_16) {
5dd90e2a
GH
1202 DPRINTF("SAI READ CAPACITY(16)\n");
1203 memset(outbuf, 0, req->cmd.xfer);
44740c38 1204 bdrv_get_geometry(s->qdev.conf.bs, &nb_sectors);
f01b5931 1205 if (!nb_sectors) {
5dd90e2a 1206 goto not_ready;
f01b5931 1207 }
7cec78b6
PB
1208 if ((req->cmd.buf[14] & 1) == 0 && req->cmd.lba) {
1209 goto illegal_request;
1210 }
69377307 1211 nb_sectors /= s->qdev.blocksize / 512;
5dd90e2a
GH
1212 /* Returned value is the address of the last sector. */
1213 nb_sectors--;
1214 /* Remember the new size for read/write sanity checking. */
7877903a 1215 s->qdev.max_lba = nb_sectors;
5dd90e2a
GH
1216 outbuf[0] = (nb_sectors >> 56) & 0xff;
1217 outbuf[1] = (nb_sectors >> 48) & 0xff;
1218 outbuf[2] = (nb_sectors >> 40) & 0xff;
1219 outbuf[3] = (nb_sectors >> 32) & 0xff;
1220 outbuf[4] = (nb_sectors >> 24) & 0xff;
1221 outbuf[5] = (nb_sectors >> 16) & 0xff;
1222 outbuf[6] = (nb_sectors >> 8) & 0xff;
1223 outbuf[7] = nb_sectors & 0xff;
1224 outbuf[8] = 0;
1225 outbuf[9] = 0;
69377307 1226 outbuf[10] = s->qdev.blocksize >> 8;
5dd90e2a 1227 outbuf[11] = 0;
ee3659e3
CH
1228 outbuf[12] = 0;
1229 outbuf[13] = get_physical_block_exp(&s->qdev.conf);
ea3bd56f
CH
1230
1231 /* set TPE bit if the format supports discard */
1232 if (s->qdev.conf.discard_granularity) {
1233 outbuf[14] = 0x80;
1234 }
1235
5dd90e2a
GH
1236 /* Protection, exponent and lowest lba field left blank. */
1237 buflen = req->cmd.xfer;
1238 break;
1239 }
1240 DPRINTF("Unsupported Service Action In\n");
1241 goto illegal_request;
5e30a07d 1242 case VERIFY_10:
88f8a5ed 1243 break;
aa5dbdc1 1244 default:
b45ef674 1245 scsi_check_condition(r, SENSE_CODE(INVALID_OPCODE));
a1f0cce2 1246 return -1;
aa5dbdc1 1247 }
aa5dbdc1
GH
1248 return buflen;
1249
1250not_ready:
44740c38 1251 if (s->tray_open || !bdrv_is_inserted(s->qdev.conf.bs)) {
b45ef674 1252 scsi_check_condition(r, SENSE_CODE(NO_MEDIUM));
a1f0cce2 1253 } else {
b45ef674 1254 scsi_check_condition(r, SENSE_CODE(LUN_NOT_READY));
a1f0cce2 1255 }
8af7a3ab 1256 return -1;
aa5dbdc1
GH
1257
1258illegal_request:
cfc606da
PB
1259 if (r->req.status == -1) {
1260 scsi_check_condition(r, SENSE_CODE(INVALID_FIELD));
1261 }
8af7a3ab 1262 return -1;
aa5dbdc1
GH
1263}
1264
2e5d83bb
PB
1265/* Execute a scsi command. Returns the length of the data expected by the
1266 command. This will be Positive for data transfers from the device
1267 (eg. disk reads), negative for transfers to the device (eg. disk writes),
1268 and zero if the command does not transfer any data. */
1269
5c6c0e51 1270static int32_t scsi_send_command(SCSIRequest *req, uint8_t *buf)
2e5d83bb 1271{
5c6c0e51
HR
1272 SCSIDiskReq *r = DO_UPCAST(SCSIDiskReq, req, req);
1273 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev);
ad2d30f7 1274 int32_t len;
a917d384 1275 uint8_t command;
aa5dbdc1 1276 int rc;
a917d384
PB
1277
1278 command = buf[0];
653c1c3f 1279 DPRINTF("Command: lun=%d tag=0x%x data=0x%02x", req->lun, req->tag, buf[0]);
2dd791b6 1280
2e5d83bb
PB
1281#ifdef DEBUG_SCSI
1282 {
1283 int i;
2dd791b6 1284 for (i = 1; i < r->req.cmd.len; i++) {
2e5d83bb
PB
1285 printf(" 0x%02x", buf[i]);
1286 }
1287 printf("\n");
1288 }
1289#endif
aa5dbdc1 1290
a917d384 1291 switch (command) {
ebf46023 1292 case TEST_UNIT_READY:
0b06c059 1293 case INQUIRY:
ebddfcbe
GH
1294 case MODE_SENSE:
1295 case MODE_SENSE_10:
3d53ba18
GH
1296 case RESERVE:
1297 case RESERVE_10:
1298 case RELEASE:
1299 case RELEASE_10:
8d3628ff 1300 case START_STOP:
c68b9f34 1301 case ALLOW_MEDIUM_REMOVAL:
5e30a07d 1302 case READ_CAPACITY_10:
02880f43 1303 case READ_TOC:
b6c251ab 1304 case READ_DVD_STRUCTURE:
38215553 1305 case GET_CONFIGURATION:
b6c251ab
PB
1306 case GET_EVENT_STATUS_NOTIFICATION:
1307 case MECHANISM_STATUS:
f6515262 1308 case SERVICE_ACTION_IN_16:
5e30a07d 1309 case VERIFY_10:
7285477a 1310 rc = scsi_disk_emulate_command(r);
8af7a3ab 1311 if (rc < 0) {
0b06c059 1312 return 0;
aa5dbdc1 1313 }
8af7a3ab
KW
1314
1315 r->iov.iov_len = rc;
0b06c059 1316 break;
0a4ac106 1317 case SYNCHRONIZE_CACHE:
c7bae6a7
PB
1318 /* The request is used as the AIO opaque value, so add a ref. */
1319 scsi_req_ref(&r->req);
44740c38
PB
1320 bdrv_acct_start(s->qdev.conf.bs, &r->acct, 0, BDRV_ACCT_FLUSH);
1321 r->req.aiocb = bdrv_aio_flush(s->qdev.conf.bs, scsi_flush_complete, r);
0a4ac106
PB
1322 if (r->req.aiocb == NULL) {
1323 scsi_flush_complete(r, -EIO);
1324 }
1325 return 0;
ebf46023
GH
1326 case READ_6:
1327 case READ_10:
bd536cf3
GH
1328 case READ_12:
1329 case READ_16:
5c6c0e51 1330 len = r->req.cmd.xfer / s->qdev.blocksize;
2dd791b6 1331 DPRINTF("Read (sector %" PRId64 ", count %d)\n", r->req.cmd.lba, len);
7877903a 1332 if (r->req.cmd.lba > s->qdev.max_lba) {
274fb0e1 1333 goto illegal_lba;
f01b5931 1334 }
69377307
PB
1335 r->sector = r->req.cmd.lba * (s->qdev.blocksize / 512);
1336 r->sector_count = len * (s->qdev.blocksize / 512);
2e5d83bb 1337 break;
ebf46023
GH
1338 case WRITE_6:
1339 case WRITE_10:
bd536cf3
GH
1340 case WRITE_12:
1341 case WRITE_16:
5e30a07d 1342 case WRITE_VERIFY_10:
ebef0bbb
BK
1343 case WRITE_VERIFY_12:
1344 case WRITE_VERIFY_16:
5c6c0e51 1345 len = r->req.cmd.xfer / s->qdev.blocksize;
ebef0bbb 1346 DPRINTF("Write %s(sector %" PRId64 ", count %d)\n",
2dd791b6
HR
1347 (command & 0xe) == 0xe ? "And Verify " : "",
1348 r->req.cmd.lba, len);
7877903a 1349 if (r->req.cmd.lba > s->qdev.max_lba) {
274fb0e1 1350 goto illegal_lba;
f01b5931 1351 }
69377307
PB
1352 r->sector = r->req.cmd.lba * (s->qdev.blocksize / 512);
1353 r->sector_count = len * (s->qdev.blocksize / 512);
2e5d83bb 1354 break;
ebef0bbb 1355 case MODE_SELECT:
2dd791b6 1356 DPRINTF("Mode Select(6) (len %lu)\n", (long)r->req.cmd.xfer);
ebef0bbb
BK
1357 /* We don't support mode parameter changes.
1358 Allow the mode parameter header + block descriptors only. */
2dd791b6 1359 if (r->req.cmd.xfer > 12) {
ebef0bbb
BK
1360 goto fail;
1361 }
1362 break;
1363 case MODE_SELECT_10:
2dd791b6 1364 DPRINTF("Mode Select(10) (len %lu)\n", (long)r->req.cmd.xfer);
ebef0bbb
BK
1365 /* We don't support mode parameter changes.
1366 Allow the mode parameter header + block descriptors only. */
2dd791b6 1367 if (r->req.cmd.xfer > 16) {
ebef0bbb
BK
1368 goto fail;
1369 }
1370 break;
1371 case SEEK_6:
1372 case SEEK_10:
2dd791b6
HR
1373 DPRINTF("Seek(%d) (sector %" PRId64 ")\n", command == SEEK_6 ? 6 : 10,
1374 r->req.cmd.lba);
7877903a 1375 if (r->req.cmd.lba > s->qdev.max_lba) {
ebef0bbb
BK
1376 goto illegal_lba;
1377 }
ea3bd56f
CH
1378 break;
1379 case WRITE_SAME_16:
5c6c0e51 1380 len = r->req.cmd.xfer / s->qdev.blocksize;
ea3bd56f
CH
1381
1382 DPRINTF("WRITE SAME(16) (sector %" PRId64 ", count %d)\n",
1383 r->req.cmd.lba, len);
1384
7877903a 1385 if (r->req.cmd.lba > s->qdev.max_lba) {
ea3bd56f
CH
1386 goto illegal_lba;
1387 }
1388
1389 /*
1390 * We only support WRITE SAME with the unmap bit set for now.
1391 */
1392 if (!(buf[1] & 0x8)) {
1393 goto fail;
1394 }
1395
69377307
PB
1396 rc = bdrv_discard(s->qdev.conf.bs,
1397 r->req.cmd.lba * (s->qdev.blocksize / 512),
1398 len * (s->qdev.blocksize / 512));
ea3bd56f
CH
1399 if (rc < 0) {
1400 /* XXX: better error code ?*/
1401 goto fail;
1402 }
1403
ebef0bbb 1404 break;
739df215
PB
1405 case REQUEST_SENSE:
1406 abort();
2e5d83bb 1407 default:
2dd791b6 1408 DPRINTF("Unknown SCSI command (%2.2x)\n", buf[0]);
b45ef674 1409 scsi_check_condition(r, SENSE_CODE(INVALID_OPCODE));
a1f0cce2 1410 return 0;
2e5d83bb 1411 fail:
b45ef674 1412 scsi_check_condition(r, SENSE_CODE(INVALID_FIELD));
2dd791b6 1413 return 0;
274fb0e1 1414 illegal_lba:
b45ef674 1415 scsi_check_condition(r, SENSE_CODE(LBA_OUT_OF_RANGE));
274fb0e1 1416 return 0;
2e5d83bb 1417 }
c87c0672 1418 if (r->sector_count == 0 && r->iov.iov_len == 0) {
b45ef674 1419 scsi_req_complete(&r->req, GOOD);
a917d384 1420 }
c87c0672 1421 len = r->sector_count * 512 + r->iov.iov_len;
efb9ee02
HR
1422 if (r->req.cmd.mode == SCSI_XFER_TO_DEV) {
1423 return -len;
a917d384 1424 } else {
f01b5931 1425 if (!r->sector_count) {
a917d384 1426 r->sector_count = -1;
f01b5931 1427 }
efb9ee02 1428 return len;
2e5d83bb 1429 }
2e5d83bb
PB
1430}
1431
e9447f35
JK
1432static void scsi_disk_reset(DeviceState *dev)
1433{
1434 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev.qdev, dev);
1435 uint64_t nb_sectors;
1436
c7b48872 1437 scsi_device_purge_requests(&s->qdev, SENSE_CODE(RESET));
e9447f35 1438
44740c38 1439 bdrv_get_geometry(s->qdev.conf.bs, &nb_sectors);
69377307 1440 nb_sectors /= s->qdev.blocksize / 512;
e9447f35
JK
1441 if (nb_sectors) {
1442 nb_sectors--;
1443 }
7877903a 1444 s->qdev.max_lba = nb_sectors;
e9447f35
JK
1445}
1446
1447static void scsi_destroy(SCSIDevice *dev)
1448{
1449 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
1450
c7b48872 1451 scsi_device_purge_requests(&s->qdev, SENSE_CODE(NO_SENSE));
f8b6cc00 1452 blockdev_mark_auto_del(s->qdev.conf.bs);
56a14938
GH
1453}
1454
7d4b4ba5 1455static void scsi_cd_change_media_cb(void *opaque, bool load)
2c6942fa 1456{
8a9c16f6
PB
1457 SCSIDiskState *s = opaque;
1458
1459 /*
1460 * When a CD gets changed, we have to report an ejected state and
1461 * then a loaded state to guests so that they detect tray
1462 * open/close and media change events. Guests that do not use
1463 * GET_EVENT_STATUS_NOTIFICATION to detect such tray open/close
1464 * states rely on this behavior.
1465 *
1466 * media_changed governs the state machine used for unit attention
1467 * report. media_event is used by GET EVENT STATUS NOTIFICATION.
1468 */
1469 s->media_changed = load;
1470 s->tray_open = !load;
1471 s->qdev.unit_attention = SENSE_CODE(UNIT_ATTENTION_NO_MEDIUM);
3c2f7c12 1472 s->media_event = true;
2c6942fa
MA
1473}
1474
e4def80b
MA
1475static bool scsi_cd_is_tray_open(void *opaque)
1476{
1477 return ((SCSIDiskState *)opaque)->tray_open;
1478}
1479
f107639a
MA
1480static bool scsi_cd_is_medium_locked(void *opaque)
1481{
1482 return ((SCSIDiskState *)opaque)->tray_locked;
1483}
1484
1485static const BlockDevOps scsi_cd_block_ops = {
2c6942fa 1486 .change_media_cb = scsi_cd_change_media_cb,
e4def80b 1487 .is_tray_open = scsi_cd_is_tray_open,
f107639a
MA
1488 .is_medium_locked = scsi_cd_is_medium_locked,
1489};
1490
8a9c16f6
PB
1491static void scsi_disk_unit_attention_reported(SCSIDevice *dev)
1492{
1493 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
1494 if (s->media_changed) {
1495 s->media_changed = false;
1496 s->qdev.unit_attention = SENSE_CODE(MEDIUM_CHANGED);
1497 }
1498}
1499
e39be482 1500static int scsi_initfn(SCSIDevice *dev)
2e5d83bb 1501{
d52affa7 1502 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
f8b6cc00 1503 DriveInfo *dinfo;
2e5d83bb 1504
f8b6cc00 1505 if (!s->qdev.conf.bs) {
1ecda02b 1506 error_report("scsi-disk: drive property not set");
d52affa7
GH
1507 return -1;
1508 }
1509
e39be482 1510 if (!s->removable && !bdrv_is_inserted(s->qdev.conf.bs)) {
98f28ad7
MA
1511 error_report("Device needs media, but drive is empty");
1512 return -1;
1513 }
1514
a0fef654 1515 if (!s->serial) {
f8b6cc00 1516 /* try to fall back to value set with legacy -drive serial=... */
44740c38 1517 dinfo = drive_get_by_blockdev(s->qdev.conf.bs);
3e1c0c9a 1518 if (*dinfo->serial) {
7267c094 1519 s->serial = g_strdup(dinfo->serial);
3e1c0c9a 1520 }
a0fef654
MA
1521 }
1522
552fee93 1523 if (!s->version) {
7267c094 1524 s->version = g_strdup(QEMU_VERSION);
552fee93
MA
1525 }
1526
44740c38 1527 if (bdrv_is_sg(s->qdev.conf.bs)) {
1ecda02b 1528 error_report("scsi-disk: unwanted /dev/sg*");
32bb404a
MA
1529 return -1;
1530 }
1531
e39be482 1532 if (s->removable) {
44740c38 1533 bdrv_set_dev_ops(s->qdev.conf.bs, &scsi_cd_block_ops, s);
2e5d83bb 1534 }
44740c38 1535 bdrv_set_buffer_alignment(s->qdev.conf.bs, s->qdev.blocksize);
8cfacf07 1536
44740c38 1537 bdrv_iostatus_enable(s->qdev.conf.bs);
1ca4d09a 1538 add_boot_device_path(s->qdev.conf.bootindex, &dev->qdev, ",0");
d52affa7
GH
1539 return 0;
1540}
1541
b443ae67
MA
1542static int scsi_hd_initfn(SCSIDevice *dev)
1543{
e39be482
PB
1544 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
1545 s->qdev.blocksize = s->qdev.conf.logical_block_size;
1546 s->qdev.type = TYPE_DISK;
1547 return scsi_initfn(&s->qdev);
b443ae67
MA
1548}
1549
1550static int scsi_cd_initfn(SCSIDevice *dev)
1551{
e39be482
PB
1552 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
1553 s->qdev.blocksize = 2048;
1554 s->qdev.type = TYPE_ROM;
1555 s->removable = true;
1556 return scsi_initfn(&s->qdev);
b443ae67
MA
1557}
1558
1559static int scsi_disk_initfn(SCSIDevice *dev)
1560{
95b5edcd 1561 DriveInfo *dinfo;
b443ae67
MA
1562
1563 if (!dev->conf.bs) {
e39be482 1564 return scsi_initfn(dev); /* ... and die there */
b443ae67
MA
1565 }
1566
e39be482
PB
1567 dinfo = drive_get_by_blockdev(dev->conf.bs);
1568 if (dinfo->media_cd) {
1569 return scsi_cd_initfn(dev);
1570 } else {
1571 return scsi_hd_initfn(dev);
1572 }
b443ae67
MA
1573}
1574
adcf2754 1575static const SCSIReqOps scsi_disk_reqops = {
8dbd4574 1576 .size = sizeof(SCSIDiskReq),
12010e7b
PB
1577 .free_req = scsi_free_request,
1578 .send_command = scsi_send_command,
1579 .read_data = scsi_read_data,
1580 .write_data = scsi_write_data,
1581 .cancel_io = scsi_cancel_io,
1582 .get_buf = scsi_get_buf,
8dbd4574
PB
1583};
1584
63db0f0e
PB
1585static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun,
1586 uint8_t *buf, void *hba_private)
8dbd4574
PB
1587{
1588 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, d);
1589 SCSIRequest *req;
8dbd4574
PB
1590
1591 req = scsi_req_alloc(&scsi_disk_reqops, &s->qdev, tag, lun, hba_private);
8dbd4574
PB
1592 return req;
1593}
1594
336a6915
PB
1595#ifdef __linux__
1596static int get_device_type(SCSIDiskState *s)
1597{
1598 BlockDriverState *bdrv = s->qdev.conf.bs;
1599 uint8_t cmd[16];
1600 uint8_t buf[36];
1601 uint8_t sensebuf[8];
1602 sg_io_hdr_t io_header;
1603 int ret;
1604
1605 memset(cmd, 0, sizeof(cmd));
1606 memset(buf, 0, sizeof(buf));
1607 cmd[0] = INQUIRY;
1608 cmd[4] = sizeof(buf);
1609
1610 memset(&io_header, 0, sizeof(io_header));
1611 io_header.interface_id = 'S';
1612 io_header.dxfer_direction = SG_DXFER_FROM_DEV;
1613 io_header.dxfer_len = sizeof(buf);
1614 io_header.dxferp = buf;
1615 io_header.cmdp = cmd;
1616 io_header.cmd_len = sizeof(cmd);
1617 io_header.mx_sb_len = sizeof(sensebuf);
1618 io_header.sbp = sensebuf;
1619 io_header.timeout = 6000; /* XXX */
1620
1621 ret = bdrv_ioctl(bdrv, SG_IO, &io_header);
1622 if (ret < 0 || io_header.driver_status || io_header.host_status) {
1623 return -1;
1624 }
1625 s->qdev.type = buf[0];
1626 s->removable = (buf[1] & 0x80) != 0;
1627 return 0;
1628}
1629
1630static int scsi_block_initfn(SCSIDevice *dev)
1631{
1632 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
1633 int sg_version;
1634 int rc;
1635
1636 if (!s->qdev.conf.bs) {
1637 error_report("scsi-block: drive property not set");
1638 return -1;
1639 }
1640
1641 /* check we are using a driver managing SG_IO (version 3 and after) */
1642 if (bdrv_ioctl(s->qdev.conf.bs, SG_GET_VERSION_NUM, &sg_version) < 0 ||
1643 sg_version < 30000) {
1644 error_report("scsi-block: scsi generic interface too old");
1645 return -1;
1646 }
1647
1648 /* get device type from INQUIRY data */
1649 rc = get_device_type(s);
1650 if (rc < 0) {
1651 error_report("scsi-block: INQUIRY failed");
1652 return -1;
1653 }
1654
1655 /* Make a guess for the block size, we'll fix it when the guest sends.
1656 * READ CAPACITY. If they don't, they likely would assume these sizes
1657 * anyway. (TODO: check in /sys).
1658 */
1659 if (s->qdev.type == TYPE_ROM || s->qdev.type == TYPE_WORM) {
1660 s->qdev.blocksize = 2048;
1661 } else {
1662 s->qdev.blocksize = 512;
1663 }
1664 return scsi_initfn(&s->qdev);
1665}
1666
1667static SCSIRequest *scsi_block_new_request(SCSIDevice *d, uint32_t tag,
1668 uint32_t lun, uint8_t *buf,
1669 void *hba_private)
1670{
1671 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, d);
1672
1673 switch (buf[0]) {
1674 case READ_6:
1675 case READ_10:
1676 case READ_12:
1677 case READ_16:
1678 case WRITE_6:
1679 case WRITE_10:
1680 case WRITE_12:
1681 case WRITE_16:
1682 case WRITE_VERIFY_10:
1683 case WRITE_VERIFY_12:
1684 case WRITE_VERIFY_16:
1685 return scsi_req_alloc(&scsi_disk_reqops, &s->qdev, tag, lun,
1686 hba_private);
1687 }
1688
1689 return scsi_req_alloc(&scsi_generic_req_ops, &s->qdev, tag, lun,
1690 hba_private);
1691}
1692#endif
1693
b443ae67
MA
1694#define DEFINE_SCSI_DISK_PROPERTIES() \
1695 DEFINE_BLOCK_PROPERTIES(SCSIDiskState, qdev.conf), \
1696 DEFINE_PROP_STRING("ver", SCSIDiskState, version), \
1697 DEFINE_PROP_STRING("serial", SCSIDiskState, serial)
1698
1699static SCSIDeviceInfo scsi_disk_info[] = {
1700 {
1701 .qdev.name = "scsi-hd",
1702 .qdev.fw_name = "disk",
1703 .qdev.desc = "virtual SCSI disk",
1704 .qdev.size = sizeof(SCSIDiskState),
1705 .qdev.reset = scsi_disk_reset,
1706 .init = scsi_hd_initfn,
1707 .destroy = scsi_destroy,
5c6c0e51 1708 .alloc_req = scsi_new_request,
8a9c16f6 1709 .unit_attention_reported = scsi_disk_unit_attention_reported,
b443ae67
MA
1710 .qdev.props = (Property[]) {
1711 DEFINE_SCSI_DISK_PROPERTIES(),
1712 DEFINE_PROP_BIT("removable", SCSIDiskState, removable, 0, false),
1713 DEFINE_PROP_END_OF_LIST(),
1714 }
1715 },{
1716 .qdev.name = "scsi-cd",
1717 .qdev.fw_name = "disk",
1718 .qdev.desc = "virtual SCSI CD-ROM",
1719 .qdev.size = sizeof(SCSIDiskState),
1720 .qdev.reset = scsi_disk_reset,
1721 .init = scsi_cd_initfn,
1722 .destroy = scsi_destroy,
5c6c0e51 1723 .alloc_req = scsi_new_request,
8a9c16f6 1724 .unit_attention_reported = scsi_disk_unit_attention_reported,
b443ae67
MA
1725 .qdev.props = (Property[]) {
1726 DEFINE_SCSI_DISK_PROPERTIES(),
1727 DEFINE_PROP_END_OF_LIST(),
1728 },
336a6915
PB
1729#ifdef __linux__
1730 },{
1731 .qdev.name = "scsi-block",
1732 .qdev.fw_name = "disk",
1733 .qdev.desc = "SCSI block device passthrough",
1734 .qdev.size = sizeof(SCSIDiskState),
1735 .qdev.reset = scsi_disk_reset,
1736 .init = scsi_block_initfn,
1737 .destroy = scsi_destroy,
1738 .alloc_req = scsi_block_new_request,
1739 .qdev.props = (Property[]) {
1740 DEFINE_SCSI_DISK_PROPERTIES(),
1741 DEFINE_PROP_END_OF_LIST(),
1742 },
1743#endif
b443ae67
MA
1744 },{
1745 .qdev.name = "scsi-disk", /* legacy -device scsi-disk */
1746 .qdev.fw_name = "disk",
1747 .qdev.desc = "virtual SCSI disk or CD-ROM (legacy)",
1748 .qdev.size = sizeof(SCSIDiskState),
1749 .qdev.reset = scsi_disk_reset,
1750 .init = scsi_disk_initfn,
1751 .destroy = scsi_destroy,
5c6c0e51 1752 .alloc_req = scsi_new_request,
8a9c16f6 1753 .unit_attention_reported = scsi_disk_unit_attention_reported,
b443ae67
MA
1754 .qdev.props = (Property[]) {
1755 DEFINE_SCSI_DISK_PROPERTIES(),
1756 DEFINE_PROP_BIT("removable", SCSIDiskState, removable, 0, false),
1757 DEFINE_PROP_END_OF_LIST(),
1758 }
1759 }
d52affa7
GH
1760};
1761
1762static void scsi_disk_register_devices(void)
1763{
b443ae67
MA
1764 int i;
1765
1766 for (i = 0; i < ARRAY_SIZE(scsi_disk_info); i++) {
1767 scsi_qdev_register(&scsi_disk_info[i]);
1768 }
8ccc2ace 1769}
d52affa7 1770device_init(scsi_disk_register_devices)