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