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