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