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