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