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