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