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