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