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