]> Git Repo - qemu.git/blob - hw/scsi-disk.c
scsi: move request parsing to common code
[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  * Modifications:
9  *  2009-Dec-12 Artyom Tarasenko : implemented stamdard inquiry for the case
10  *                                 when the allocation length of CDB is smaller
11  *                                 than 36.
12  *  2009-Oct-13 Artyom Tarasenko : implemented the block descriptor in the
13  *                                 MODE SENSE response.
14  *
15  * This code is licensed under the LGPL.
16  *
17  * Note that this file only handles the SCSI architecture model and device
18  * commands.  Emulation of interface/link layer protocols is handled by
19  * the host adapter emulator.
20  */
21
22 //#define DEBUG_SCSI
23
24 #ifdef DEBUG_SCSI
25 #define DPRINTF(fmt, ...) \
26 do { printf("scsi-disk: " fmt , ## __VA_ARGS__); } while (0)
27 #else
28 #define DPRINTF(fmt, ...) do {} while(0)
29 #endif
30
31 #define BADF(fmt, ...) \
32 do { fprintf(stderr, "scsi-disk: " fmt , ## __VA_ARGS__); } while (0)
33
34 #include "qemu-common.h"
35 #include "qemu-error.h"
36 #include "scsi.h"
37 #include "scsi-defs.h"
38 #include "sysemu.h"
39 #include "blockdev.h"
40
41 #define SCSI_DMA_BUF_SIZE    131072
42 #define SCSI_MAX_INQUIRY_LEN 256
43
44 #define SCSI_REQ_STATUS_RETRY           0x01
45 #define SCSI_REQ_STATUS_RETRY_TYPE_MASK 0x06
46 #define SCSI_REQ_STATUS_RETRY_READ      0x00
47 #define SCSI_REQ_STATUS_RETRY_WRITE     0x02
48 #define SCSI_REQ_STATUS_RETRY_FLUSH     0x04
49
50 typedef struct SCSIDiskState SCSIDiskState;
51
52 typedef struct SCSIDiskReq {
53     SCSIRequest req;
54     /* Both sector and sector_count are in terms of qemu 512 byte blocks.  */
55     uint64_t sector;
56     uint32_t sector_count;
57     struct iovec iov;
58     QEMUIOVector qiov;
59     uint32_t status;
60 } SCSIDiskReq;
61
62 struct SCSIDiskState
63 {
64     SCSIDevice qdev;
65     BlockDriverState *bs;
66     /* The qemu block layer uses a fixed 512 byte sector size.
67        This is the number of 512 byte blocks in a single scsi sector.  */
68     int cluster_size;
69     uint32_t removable;
70     uint64_t max_lba;
71     QEMUBH *bh;
72     char *version;
73     char *serial;
74 };
75
76 static int scsi_handle_rw_error(SCSIDiskReq *r, int error, int type);
77 static int scsi_disk_emulate_command(SCSIDiskReq *r, uint8_t *outbuf);
78
79 static void scsi_free_request(SCSIRequest *req)
80 {
81     SCSIDiskReq *r = DO_UPCAST(SCSIDiskReq, req, req);
82
83     qemu_vfree(r->iov.iov_base);
84 }
85
86 /* Helper function for command completion with sense.  */
87 static void scsi_check_condition(SCSIDiskReq *r, SCSISense sense)
88 {
89     DPRINTF("Command complete tag=0x%x status=%d sense=%d/%d/%d\n",
90             r->req.tag, status, sense.key, sense.asc, sense.ascq);
91     scsi_req_build_sense(&r->req, sense);
92     scsi_req_complete(&r->req, CHECK_CONDITION);
93 }
94
95 /* Cancel a pending data transfer.  */
96 static void scsi_cancel_io(SCSIRequest *req)
97 {
98     SCSIDiskReq *r = DO_UPCAST(SCSIDiskReq, req, req);
99
100     DPRINTF("Cancel tag=0x%x\n", req->tag);
101     if (r->req.aiocb) {
102         bdrv_aio_cancel(r->req.aiocb);
103     }
104     r->req.aiocb = NULL;
105 }
106
107 static void scsi_read_complete(void * opaque, int ret)
108 {
109     SCSIDiskReq *r = (SCSIDiskReq *)opaque;
110     int n;
111
112     r->req.aiocb = NULL;
113
114     if (ret) {
115         if (scsi_handle_rw_error(r, -ret, SCSI_REQ_STATUS_RETRY_READ)) {
116             return;
117         }
118     }
119
120     DPRINTF("Data ready tag=0x%x len=%zd\n", r->req.tag, r->iov.iov_len);
121
122     n = r->iov.iov_len / 512;
123     r->sector += n;
124     r->sector_count -= n;
125     scsi_req_data(&r->req, r->iov.iov_len);
126 }
127
128
129 /* Read more data from scsi device into buffer.  */
130 static void scsi_read_data(SCSIRequest *req)
131 {
132     SCSIDiskReq *r = DO_UPCAST(SCSIDiskReq, req, req);
133     SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
134     uint32_t n;
135
136     if (r->sector_count == (uint32_t)-1) {
137         DPRINTF("Read buf_len=%zd\n", r->iov.iov_len);
138         r->sector_count = 0;
139         scsi_req_data(&r->req, r->iov.iov_len);
140         return;
141     }
142     DPRINTF("Read sector_count=%d\n", r->sector_count);
143     if (r->sector_count == 0) {
144         /* This also clears the sense buffer for REQUEST SENSE.  */
145         scsi_req_complete(&r->req, GOOD);
146         return;
147     }
148
149     /* No data transfer may already be in progress */
150     assert(r->req.aiocb == NULL);
151
152     if (r->req.cmd.mode == SCSI_XFER_TO_DEV) {
153         DPRINTF("Data transfer direction invalid\n");
154         scsi_read_complete(r, -EINVAL);
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->bs, r->sector, &r->qiov, n,
165                               scsi_read_complete, r);
166     if (r->req.aiocb == NULL) {
167         scsi_read_complete(r, -EIO);
168     }
169 }
170
171 static int scsi_handle_rw_error(SCSIDiskReq *r, int error, int type)
172 {
173     int is_read = (type == SCSI_REQ_STATUS_RETRY_READ);
174     SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
175     BlockErrorAction action = bdrv_get_on_error(s->bs, is_read);
176
177     if (action == BLOCK_ERR_IGNORE) {
178         bdrv_mon_event(s->bs, BDRV_ACTION_IGNORE, is_read);
179         return 0;
180     }
181
182     if ((error == ENOSPC && action == BLOCK_ERR_STOP_ENOSPC)
183             || action == BLOCK_ERR_STOP_ANY) {
184
185         type &= SCSI_REQ_STATUS_RETRY_TYPE_MASK;
186         r->status |= SCSI_REQ_STATUS_RETRY | type;
187
188         bdrv_mon_event(s->bs, BDRV_ACTION_STOP, is_read);
189         vm_stop(VMSTOP_DISKFULL);
190     } else {
191         switch (error) {
192         case ENOMEM:
193             scsi_check_condition(r, SENSE_CODE(TARGET_FAILURE));
194             break;
195         case EINVAL:
196             scsi_check_condition(r, SENSE_CODE(INVALID_FIELD));
197             break;
198         default:
199             scsi_check_condition(r, SENSE_CODE(IO_ERROR));
200             break;
201         }
202         bdrv_mon_event(s->bs, BDRV_ACTION_REPORT, is_read);
203     }
204     return 1;
205 }
206
207 static void scsi_write_complete(void * opaque, int ret)
208 {
209     SCSIDiskReq *r = (SCSIDiskReq *)opaque;
210     uint32_t len;
211     uint32_t n;
212
213     r->req.aiocb = NULL;
214
215     if (ret) {
216         if (scsi_handle_rw_error(r, -ret, SCSI_REQ_STATUS_RETRY_WRITE)) {
217             return;
218         }
219     }
220
221     n = r->iov.iov_len / 512;
222     r->sector += n;
223     r->sector_count -= n;
224     if (r->sector_count == 0) {
225         scsi_req_complete(&r->req, GOOD);
226     } else {
227         len = r->sector_count * 512;
228         if (len > SCSI_DMA_BUF_SIZE) {
229             len = SCSI_DMA_BUF_SIZE;
230         }
231         r->iov.iov_len = len;
232         DPRINTF("Write complete tag=0x%x more=%d\n", r->req.tag, len);
233         scsi_req_data(&r->req, len);
234     }
235 }
236
237 static void scsi_write_data(SCSIRequest *req)
238 {
239     SCSIDiskReq *r = DO_UPCAST(SCSIDiskReq, req, req);
240     SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
241     uint32_t n;
242
243     /* No data transfer may already be in progress */
244     assert(r->req.aiocb == NULL);
245
246     if (r->req.cmd.mode != SCSI_XFER_TO_DEV) {
247         DPRINTF("Data transfer direction invalid\n");
248         scsi_write_complete(r, -EINVAL);
249         return;
250     }
251
252     n = r->iov.iov_len / 512;
253     if (n) {
254         qemu_iovec_init_external(&r->qiov, &r->iov, 1);
255         r->req.aiocb = bdrv_aio_writev(s->bs, r->sector, &r->qiov, n,
256                                    scsi_write_complete, r);
257         if (r->req.aiocb == NULL) {
258             scsi_write_complete(r, -ENOMEM);
259         }
260     } else {
261         /* Invoke completion routine to fetch data from host.  */
262         scsi_write_complete(r, 0);
263     }
264 }
265
266 static void scsi_dma_restart_bh(void *opaque)
267 {
268     SCSIDiskState *s = opaque;
269     SCSIRequest *req;
270     SCSIDiskReq *r;
271
272     qemu_bh_delete(s->bh);
273     s->bh = NULL;
274
275     QTAILQ_FOREACH(req, &s->qdev.requests, next) {
276         r = DO_UPCAST(SCSIDiskReq, req, req);
277         if (r->status & SCSI_REQ_STATUS_RETRY) {
278             int status = r->status;
279             int ret;
280
281             r->status &=
282                 ~(SCSI_REQ_STATUS_RETRY | SCSI_REQ_STATUS_RETRY_TYPE_MASK);
283
284             switch (status & SCSI_REQ_STATUS_RETRY_TYPE_MASK) {
285             case SCSI_REQ_STATUS_RETRY_READ:
286                 scsi_read_data(&r->req);
287                 break;
288             case SCSI_REQ_STATUS_RETRY_WRITE:
289                 scsi_write_data(&r->req);
290                 break;
291             case SCSI_REQ_STATUS_RETRY_FLUSH:
292                 ret = scsi_disk_emulate_command(r, r->iov.iov_base);
293                 if (ret == 0) {
294                     scsi_req_complete(&r->req, GOOD);
295                 }
296             }
297         }
298     }
299 }
300
301 static void scsi_dma_restart_cb(void *opaque, int running, int reason)
302 {
303     SCSIDiskState *s = opaque;
304
305     if (!running)
306         return;
307
308     if (!s->bh) {
309         s->bh = qemu_bh_new(scsi_dma_restart_bh, s);
310         qemu_bh_schedule(s->bh);
311     }
312 }
313
314 /* Return a pointer to the data buffer.  */
315 static uint8_t *scsi_get_buf(SCSIRequest *req)
316 {
317     SCSIDiskReq *r = DO_UPCAST(SCSIDiskReq, req, req);
318
319     return (uint8_t *)r->iov.iov_base;
320 }
321
322 static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf)
323 {
324     SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev);
325     int buflen = 0;
326
327     if (req->cmd.buf[1] & 0x2) {
328         /* Command support data - optional, not implemented */
329         BADF("optional INQUIRY command support request not implemented\n");
330         return -1;
331     }
332
333     if (req->cmd.buf[1] & 0x1) {
334         /* Vital product data */
335         uint8_t page_code = req->cmd.buf[2];
336         if (req->cmd.xfer < 4) {
337             BADF("Error: Inquiry (EVPD[%02X]) buffer size %zd is "
338                  "less than 4\n", page_code, req->cmd.xfer);
339             return -1;
340         }
341
342         if (s->qdev.type == TYPE_ROM) {
343             outbuf[buflen++] = 5;
344         } else {
345             outbuf[buflen++] = 0;
346         }
347         outbuf[buflen++] = page_code ; // this page
348         outbuf[buflen++] = 0x00;
349
350         switch (page_code) {
351         case 0x00: /* Supported page codes, mandatory */
352         {
353             int pages;
354             DPRINTF("Inquiry EVPD[Supported pages] "
355                     "buffer size %zd\n", req->cmd.xfer);
356             pages = buflen++;
357             outbuf[buflen++] = 0x00; // list of supported pages (this page)
358             if (s->serial)
359                 outbuf[buflen++] = 0x80; // unit serial number
360             outbuf[buflen++] = 0x83; // device identification
361             if (s->qdev.type == TYPE_DISK) {
362                 outbuf[buflen++] = 0xb0; // block limits
363                 outbuf[buflen++] = 0xb2; // thin provisioning
364             }
365             outbuf[pages] = buflen - pages - 1; // number of pages
366             break;
367         }
368         case 0x80: /* Device serial number, optional */
369         {
370             int l;
371
372             if (!s->serial) {
373                 DPRINTF("Inquiry (EVPD[Serial number] not supported\n");
374                 return -1;
375             }
376
377             l = strlen(s->serial);
378             if (l > req->cmd.xfer)
379                 l = req->cmd.xfer;
380             if (l > 20)
381                 l = 20;
382
383             DPRINTF("Inquiry EVPD[Serial number] "
384                     "buffer size %zd\n", req->cmd.xfer);
385             outbuf[buflen++] = l;
386             memcpy(outbuf+buflen, s->serial, l);
387             buflen += l;
388             break;
389         }
390
391         case 0x83: /* Device identification page, mandatory */
392         {
393             int max_len = 255 - 8;
394             int id_len = strlen(bdrv_get_device_name(s->bs));
395
396             if (id_len > max_len)
397                 id_len = max_len;
398             DPRINTF("Inquiry EVPD[Device identification] "
399                     "buffer size %zd\n", req->cmd.xfer);
400
401             outbuf[buflen++] = 4 + id_len;
402             outbuf[buflen++] = 0x2; // ASCII
403             outbuf[buflen++] = 0;   // not officially assigned
404             outbuf[buflen++] = 0;   // reserved
405             outbuf[buflen++] = id_len; // length of data following
406
407             memcpy(outbuf+buflen, bdrv_get_device_name(s->bs), id_len);
408             buflen += id_len;
409             break;
410         }
411         case 0xb0: /* block limits */
412         {
413             unsigned int unmap_sectors =
414                     s->qdev.conf.discard_granularity / s->qdev.blocksize;
415             unsigned int min_io_size =
416                     s->qdev.conf.min_io_size / s->qdev.blocksize;
417             unsigned int opt_io_size =
418                     s->qdev.conf.opt_io_size / s->qdev.blocksize;
419
420             if (s->qdev.type == TYPE_ROM) {
421                 DPRINTF("Inquiry (EVPD[%02X] not supported for CDROM\n",
422                         page_code);
423                 return -1;
424             }
425             /* required VPD size with unmap support */
426             outbuf[3] = buflen = 0x3c;
427
428             memset(outbuf + 4, 0, buflen - 4);
429
430             /* optimal transfer length granularity */
431             outbuf[6] = (min_io_size >> 8) & 0xff;
432             outbuf[7] = min_io_size & 0xff;
433
434             /* optimal transfer length */
435             outbuf[12] = (opt_io_size >> 24) & 0xff;
436             outbuf[13] = (opt_io_size >> 16) & 0xff;
437             outbuf[14] = (opt_io_size >> 8) & 0xff;
438             outbuf[15] = opt_io_size & 0xff;
439
440             /* optimal unmap granularity */
441             outbuf[28] = (unmap_sectors >> 24) & 0xff;
442             outbuf[29] = (unmap_sectors >> 16) & 0xff;
443             outbuf[30] = (unmap_sectors >> 8) & 0xff;
444             outbuf[31] = unmap_sectors & 0xff;
445             break;
446         }
447         case 0xb2: /* thin provisioning */
448         {
449             outbuf[3] = buflen = 8;
450             outbuf[4] = 0;
451             outbuf[5] = 0x40; /* write same with unmap supported */
452             outbuf[6] = 0;
453             outbuf[7] = 0;
454             break;
455         }
456         default:
457             BADF("Error: unsupported Inquiry (EVPD[%02X]) "
458                  "buffer size %zd\n", page_code, req->cmd.xfer);
459             return -1;
460         }
461         /* done with EVPD */
462         return buflen;
463     }
464
465     /* Standard INQUIRY data */
466     if (req->cmd.buf[2] != 0) {
467         BADF("Error: Inquiry (STANDARD) page or code "
468              "is non-zero [%02X]\n", req->cmd.buf[2]);
469         return -1;
470     }
471
472     /* PAGE CODE == 0 */
473     if (req->cmd.xfer < 5) {
474         BADF("Error: Inquiry (STANDARD) buffer size %zd "
475              "is less than 5\n", req->cmd.xfer);
476         return -1;
477     }
478
479     buflen = req->cmd.xfer;
480     if (buflen > SCSI_MAX_INQUIRY_LEN)
481         buflen = SCSI_MAX_INQUIRY_LEN;
482
483     memset(outbuf, 0, buflen);
484
485     if (req->lun) {
486         outbuf[0] = 0x7f;       /* LUN not supported */
487         return buflen;
488     }
489
490     outbuf[0] = s->qdev.type & 0x1f;
491     if (s->qdev.type == TYPE_ROM) {
492         outbuf[1] = 0x80;
493         memcpy(&outbuf[16], "QEMU CD-ROM     ", 16);
494     } else {
495         outbuf[1] = s->removable ? 0x80 : 0;
496         memcpy(&outbuf[16], "QEMU HARDDISK   ", 16);
497     }
498     memcpy(&outbuf[8], "QEMU    ", 8);
499     memset(&outbuf[32], 0, 4);
500     memcpy(&outbuf[32], s->version, MIN(4, strlen(s->version)));
501     /*
502      * We claim conformance to SPC-3, which is required for guests
503      * to ask for modern features like READ CAPACITY(16) or the
504      * block characteristics VPD page by default.  Not all of SPC-3
505      * is actually implemented, but we're good enough.
506      */
507     outbuf[2] = 5;
508     outbuf[3] = 2; /* Format 2 */
509
510     if (buflen > 36) {
511         outbuf[4] = buflen - 5; /* Additional Length = (Len - 1) - 4 */
512     } else {
513         /* If the allocation length of CDB is too small,
514                the additional length is not adjusted */
515         outbuf[4] = 36 - 5;
516     }
517
518     /* Sync data transfer and TCQ.  */
519     outbuf[7] = 0x10 | (req->bus->tcq ? 0x02 : 0);
520     return buflen;
521 }
522
523 static int mode_sense_page(SCSIRequest *req, int page, uint8_t *p,
524                            int page_control)
525 {
526     SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev);
527     BlockDriverState *bdrv = s->bs;
528     int cylinders, heads, secs;
529
530     /*
531      * If Changeable Values are requested, a mask denoting those mode parameters
532      * that are changeable shall be returned. As we currently don't support
533      * parameter changes via MODE_SELECT all bits are returned set to zero.
534      * The buffer was already menset to zero by the caller of this function.
535      */
536     switch (page) {
537     case 4: /* Rigid disk device geometry page. */
538         p[0] = 4;
539         p[1] = 0x16;
540         if (page_control == 1) { /* Changeable Values */
541             return p[1] + 2;
542         }
543         /* if a geometry hint is available, use it */
544         bdrv_get_geometry_hint(bdrv, &cylinders, &heads, &secs);
545         p[2] = (cylinders >> 16) & 0xff;
546         p[3] = (cylinders >> 8) & 0xff;
547         p[4] = cylinders & 0xff;
548         p[5] = heads & 0xff;
549         /* Write precomp start cylinder, disabled */
550         p[6] = (cylinders >> 16) & 0xff;
551         p[7] = (cylinders >> 8) & 0xff;
552         p[8] = cylinders & 0xff;
553         /* Reduced current start cylinder, disabled */
554         p[9] = (cylinders >> 16) & 0xff;
555         p[10] = (cylinders >> 8) & 0xff;
556         p[11] = cylinders & 0xff;
557         /* Device step rate [ns], 200ns */
558         p[12] = 0;
559         p[13] = 200;
560         /* Landing zone cylinder */
561         p[14] = 0xff;
562         p[15] =  0xff;
563         p[16] = 0xff;
564         /* Medium rotation rate [rpm], 5400 rpm */
565         p[20] = (5400 >> 8) & 0xff;
566         p[21] = 5400 & 0xff;
567         return p[1] + 2;
568
569     case 5: /* Flexible disk device geometry page. */
570         p[0] = 5;
571         p[1] = 0x1e;
572         if (page_control == 1) { /* Changeable Values */
573             return p[1] + 2;
574         }
575         /* Transfer rate [kbit/s], 5Mbit/s */
576         p[2] = 5000 >> 8;
577         p[3] = 5000 & 0xff;
578         /* if a geometry hint is available, use it */
579         bdrv_get_geometry_hint(bdrv, &cylinders, &heads, &secs);
580         p[4] = heads & 0xff;
581         p[5] = secs & 0xff;
582         p[6] = s->cluster_size * 2;
583         p[8] = (cylinders >> 8) & 0xff;
584         p[9] = cylinders & 0xff;
585         /* Write precomp start cylinder, disabled */
586         p[10] = (cylinders >> 8) & 0xff;
587         p[11] = cylinders & 0xff;
588         /* Reduced current start cylinder, disabled */
589         p[12] = (cylinders >> 8) & 0xff;
590         p[13] = cylinders & 0xff;
591         /* Device step rate [100us], 100us */
592         p[14] = 0;
593         p[15] = 1;
594         /* Device step pulse width [us], 1us */
595         p[16] = 1;
596         /* Device head settle delay [100us], 100us */
597         p[17] = 0;
598         p[18] = 1;
599         /* Motor on delay [0.1s], 0.1s */
600         p[19] = 1;
601         /* Motor off delay [0.1s], 0.1s */
602         p[20] = 1;
603         /* Medium rotation rate [rpm], 5400 rpm */
604         p[28] = (5400 >> 8) & 0xff;
605         p[29] = 5400 & 0xff;
606         return p[1] + 2;
607
608     case 8: /* Caching page.  */
609         p[0] = 8;
610         p[1] = 0x12;
611         if (page_control == 1) { /* Changeable Values */
612             return p[1] + 2;
613         }
614         if (bdrv_enable_write_cache(s->bs)) {
615             p[2] = 4; /* WCE */
616         }
617         return p[1] + 2;
618
619     case 0x2a: /* CD Capabilities and Mechanical Status page. */
620         if (s->qdev.type != TYPE_ROM)
621             return 0;
622         p[0] = 0x2a;
623         p[1] = 0x14;
624         if (page_control == 1) { /* Changeable Values */
625             return p[1] + 2;
626         }
627         p[2] = 3; // CD-R & CD-RW read
628         p[3] = 0; // Writing not supported
629         p[4] = 0x7f; /* Audio, composite, digital out,
630                         mode 2 form 1&2, multi session */
631         p[5] = 0xff; /* CD DA, DA accurate, RW supported,
632                         RW corrected, C2 errors, ISRC,
633                         UPC, Bar code */
634         p[6] = 0x2d | (bdrv_is_locked(s->bs)? 2 : 0);
635         /* Locking supported, jumper present, eject, tray */
636         p[7] = 0; /* no volume & mute control, no
637                      changer */
638         p[8] = (50 * 176) >> 8; // 50x read speed
639         p[9] = (50 * 176) & 0xff;
640         p[10] = 0 >> 8; // No volume
641         p[11] = 0 & 0xff;
642         p[12] = 2048 >> 8; // 2M buffer
643         p[13] = 2048 & 0xff;
644         p[14] = (16 * 176) >> 8; // 16x read speed current
645         p[15] = (16 * 176) & 0xff;
646         p[18] = (16 * 176) >> 8; // 16x write speed
647         p[19] = (16 * 176) & 0xff;
648         p[20] = (16 * 176) >> 8; // 16x write speed current
649         p[21] = (16 * 176) & 0xff;
650         return p[1] + 2;
651
652     default:
653         return 0;
654     }
655 }
656
657 static int scsi_disk_emulate_mode_sense(SCSIRequest *req, uint8_t *outbuf)
658 {
659     SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev);
660     uint64_t nb_sectors;
661     int page, dbd, buflen, page_control;
662     uint8_t *p;
663     uint8_t dev_specific_param;
664
665     dbd = req->cmd.buf[1]  & 0x8;
666     page = req->cmd.buf[2] & 0x3f;
667     page_control = (req->cmd.buf[2] & 0xc0) >> 6;
668     DPRINTF("Mode Sense(%d) (page %d, xfer %zd, page_control %d)\n",
669         (req->cmd.buf[0] == MODE_SENSE) ? 6 : 10, page, req->cmd.xfer, page_control);
670     memset(outbuf, 0, req->cmd.xfer);
671     p = outbuf;
672
673     if (bdrv_is_read_only(s->bs)) {
674         dev_specific_param = 0x80; /* Readonly.  */
675     } else {
676         dev_specific_param = 0x00;
677     }
678
679     if (req->cmd.buf[0] == MODE_SENSE) {
680         p[1] = 0; /* Default media type.  */
681         p[2] = dev_specific_param;
682         p[3] = 0; /* Block descriptor length.  */
683         p += 4;
684     } else { /* MODE_SENSE_10 */
685         p[2] = 0; /* Default media type.  */
686         p[3] = dev_specific_param;
687         p[6] = p[7] = 0; /* Block descriptor length.  */
688         p += 8;
689     }
690
691     bdrv_get_geometry(s->bs, &nb_sectors);
692     if (!dbd && nb_sectors) {
693         if (req->cmd.buf[0] == MODE_SENSE) {
694             outbuf[3] = 8; /* Block descriptor length  */
695         } else { /* MODE_SENSE_10 */
696             outbuf[7] = 8; /* Block descriptor length  */
697         }
698         nb_sectors /= s->cluster_size;
699         if (nb_sectors > 0xffffff)
700             nb_sectors = 0;
701         p[0] = 0; /* media density code */
702         p[1] = (nb_sectors >> 16) & 0xff;
703         p[2] = (nb_sectors >> 8) & 0xff;
704         p[3] = nb_sectors & 0xff;
705         p[4] = 0; /* reserved */
706         p[5] = 0; /* bytes 5-7 are the sector size in bytes */
707         p[6] = s->cluster_size * 2;
708         p[7] = 0;
709         p += 8;
710     }
711
712     if (page_control == 3) { /* Saved Values */
713         return -1; /* ILLEGAL_REQUEST */
714     }
715
716     switch (page) {
717     case 0x04:
718     case 0x05:
719     case 0x08:
720     case 0x2a:
721         p += mode_sense_page(req, page, p, page_control);
722         break;
723     case 0x3f:
724         p += mode_sense_page(req, 0x08, p, page_control);
725         p += mode_sense_page(req, 0x2a, p, page_control);
726         break;
727     default:
728         return -1; /* ILLEGAL_REQUEST */
729     }
730
731     buflen = p - outbuf;
732     /*
733      * The mode data length field specifies the length in bytes of the
734      * following data that is available to be transferred. The mode data
735      * length does not include itself.
736      */
737     if (req->cmd.buf[0] == MODE_SENSE) {
738         outbuf[0] = buflen - 1;
739     } else { /* MODE_SENSE_10 */
740         outbuf[0] = ((buflen - 2) >> 8) & 0xff;
741         outbuf[1] = (buflen - 2) & 0xff;
742     }
743     if (buflen > req->cmd.xfer)
744         buflen = req->cmd.xfer;
745     return buflen;
746 }
747
748 static int scsi_disk_emulate_read_toc(SCSIRequest *req, uint8_t *outbuf)
749 {
750     SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev);
751     int start_track, format, msf, toclen;
752     uint64_t nb_sectors;
753
754     msf = req->cmd.buf[1] & 2;
755     format = req->cmd.buf[2] & 0xf;
756     start_track = req->cmd.buf[6];
757     bdrv_get_geometry(s->bs, &nb_sectors);
758     DPRINTF("Read TOC (track %d format %d msf %d)\n", start_track, format, msf >> 1);
759     nb_sectors /= s->cluster_size;
760     switch (format) {
761     case 0:
762         toclen = cdrom_read_toc(nb_sectors, outbuf, msf, start_track);
763         break;
764     case 1:
765         /* multi session : only a single session defined */
766         toclen = 12;
767         memset(outbuf, 0, 12);
768         outbuf[1] = 0x0a;
769         outbuf[2] = 0x01;
770         outbuf[3] = 0x01;
771         break;
772     case 2:
773         toclen = cdrom_read_toc_raw(nb_sectors, outbuf, msf, start_track);
774         break;
775     default:
776         return -1;
777     }
778     if (toclen > req->cmd.xfer)
779         toclen = req->cmd.xfer;
780     return toclen;
781 }
782
783 static int scsi_disk_emulate_command(SCSIDiskReq *r, uint8_t *outbuf)
784 {
785     SCSIRequest *req = &r->req;
786     SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev);
787     uint64_t nb_sectors;
788     int buflen = 0;
789     int ret;
790
791     switch (req->cmd.buf[0]) {
792     case TEST_UNIT_READY:
793         if (!bdrv_is_inserted(s->bs))
794             goto not_ready;
795         break;
796     case REQUEST_SENSE:
797         if (req->cmd.xfer < 4)
798             goto illegal_request;
799         buflen = scsi_device_get_sense(&s->qdev, outbuf, req->cmd.xfer,
800                                        (req->cmd.buf[1] & 1) == 0);
801         break;
802     case INQUIRY:
803         buflen = scsi_disk_emulate_inquiry(req, outbuf);
804         if (buflen < 0)
805             goto illegal_request;
806         break;
807     case MODE_SENSE:
808     case MODE_SENSE_10:
809         buflen = scsi_disk_emulate_mode_sense(req, outbuf);
810         if (buflen < 0)
811             goto illegal_request;
812         break;
813     case READ_TOC:
814         buflen = scsi_disk_emulate_read_toc(req, outbuf);
815         if (buflen < 0)
816             goto illegal_request;
817         break;
818     case RESERVE:
819         if (req->cmd.buf[1] & 1)
820             goto illegal_request;
821         break;
822     case RESERVE_10:
823         if (req->cmd.buf[1] & 3)
824             goto illegal_request;
825         break;
826     case RELEASE:
827         if (req->cmd.buf[1] & 1)
828             goto illegal_request;
829         break;
830     case RELEASE_10:
831         if (req->cmd.buf[1] & 3)
832             goto illegal_request;
833         break;
834     case START_STOP:
835         if (s->qdev.type == TYPE_ROM && (req->cmd.buf[4] & 2)) {
836             /* load/eject medium */
837             bdrv_eject(s->bs, !(req->cmd.buf[4] & 1));
838         }
839         break;
840     case ALLOW_MEDIUM_REMOVAL:
841         bdrv_set_locked(s->bs, req->cmd.buf[4] & 1);
842         break;
843     case READ_CAPACITY_10:
844         /* The normal LEN field for this command is zero.  */
845         memset(outbuf, 0, 8);
846         bdrv_get_geometry(s->bs, &nb_sectors);
847         if (!nb_sectors)
848             goto not_ready;
849         nb_sectors /= s->cluster_size;
850         /* Returned value is the address of the last sector.  */
851         nb_sectors--;
852         /* Remember the new size for read/write sanity checking. */
853         s->max_lba = nb_sectors;
854         /* Clip to 2TB, instead of returning capacity modulo 2TB. */
855         if (nb_sectors > UINT32_MAX)
856             nb_sectors = UINT32_MAX;
857         outbuf[0] = (nb_sectors >> 24) & 0xff;
858         outbuf[1] = (nb_sectors >> 16) & 0xff;
859         outbuf[2] = (nb_sectors >> 8) & 0xff;
860         outbuf[3] = nb_sectors & 0xff;
861         outbuf[4] = 0;
862         outbuf[5] = 0;
863         outbuf[6] = s->cluster_size * 2;
864         outbuf[7] = 0;
865         buflen = 8;
866         break;
867     case SYNCHRONIZE_CACHE:
868         ret = bdrv_flush(s->bs);
869         if (ret < 0) {
870             if (scsi_handle_rw_error(r, -ret, SCSI_REQ_STATUS_RETRY_FLUSH)) {
871                 return -1;
872             }
873         }
874         break;
875     case GET_CONFIGURATION:
876         memset(outbuf, 0, 8);
877         /* ??? This should probably return much more information.  For now
878            just return the basic header indicating the CD-ROM profile.  */
879         outbuf[7] = 8; // CD-ROM
880         buflen = 8;
881         break;
882     case SERVICE_ACTION_IN:
883         /* Service Action In subcommands. */
884         if ((req->cmd.buf[1] & 31) == 0x10) {
885             DPRINTF("SAI READ CAPACITY(16)\n");
886             memset(outbuf, 0, req->cmd.xfer);
887             bdrv_get_geometry(s->bs, &nb_sectors);
888             if (!nb_sectors)
889                 goto not_ready;
890             nb_sectors /= s->cluster_size;
891             /* Returned value is the address of the last sector.  */
892             nb_sectors--;
893             /* Remember the new size for read/write sanity checking. */
894             s->max_lba = nb_sectors;
895             outbuf[0] = (nb_sectors >> 56) & 0xff;
896             outbuf[1] = (nb_sectors >> 48) & 0xff;
897             outbuf[2] = (nb_sectors >> 40) & 0xff;
898             outbuf[3] = (nb_sectors >> 32) & 0xff;
899             outbuf[4] = (nb_sectors >> 24) & 0xff;
900             outbuf[5] = (nb_sectors >> 16) & 0xff;
901             outbuf[6] = (nb_sectors >> 8) & 0xff;
902             outbuf[7] = nb_sectors & 0xff;
903             outbuf[8] = 0;
904             outbuf[9] = 0;
905             outbuf[10] = s->cluster_size * 2;
906             outbuf[11] = 0;
907             outbuf[12] = 0;
908             outbuf[13] = get_physical_block_exp(&s->qdev.conf);
909
910             /* set TPE bit if the format supports discard */
911             if (s->qdev.conf.discard_granularity) {
912                 outbuf[14] = 0x80;
913             }
914
915             /* Protection, exponent and lowest lba field left blank. */
916             buflen = req->cmd.xfer;
917             break;
918         }
919         DPRINTF("Unsupported Service Action In\n");
920         goto illegal_request;
921     case REPORT_LUNS:
922         if (req->cmd.xfer < 16)
923             goto illegal_request;
924         memset(outbuf, 0, 16);
925         outbuf[3] = 8;
926         buflen = 16;
927         break;
928     case VERIFY_10:
929         break;
930     default:
931         scsi_check_condition(r, SENSE_CODE(INVALID_OPCODE));
932         return -1;
933     }
934     return buflen;
935
936 not_ready:
937     if (!bdrv_is_inserted(s->bs)) {
938         scsi_check_condition(r, SENSE_CODE(NO_MEDIUM));
939     } else {
940         scsi_check_condition(r, SENSE_CODE(LUN_NOT_READY));
941     }
942     return -1;
943
944 illegal_request:
945     scsi_check_condition(r, SENSE_CODE(INVALID_FIELD));
946     return -1;
947 }
948
949 /* Execute a scsi command.  Returns the length of the data expected by the
950    command.  This will be Positive for data transfers from the device
951    (eg. disk reads), negative for transfers to the device (eg. disk writes),
952    and zero if the command does not transfer any data.  */
953
954 static int32_t scsi_send_command(SCSIRequest *req, uint8_t *buf)
955 {
956     SCSIDiskReq *r = DO_UPCAST(SCSIDiskReq, req, req);
957     SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev);
958     int32_t len;
959     uint8_t command;
960     uint8_t *outbuf;
961     int rc;
962
963     command = buf[0];
964     outbuf = (uint8_t *)r->iov.iov_base;
965     DPRINTF("Command: lun=%d tag=0x%x data=0x%02x", req->lun, req->tag, buf[0]);
966
967 #ifdef DEBUG_SCSI
968     {
969         int i;
970         for (i = 1; i < r->req.cmd.len; i++) {
971             printf(" 0x%02x", buf[i]);
972         }
973         printf("\n");
974     }
975 #endif
976
977     if (req->lun) {
978         /* Only LUN 0 supported.  */
979         DPRINTF("Unimplemented LUN %d\n", req->lun);
980         if (command != REQUEST_SENSE && command != INQUIRY) {
981             scsi_check_condition(r, SENSE_CODE(LUN_NOT_SUPPORTED));
982             return 0;
983         }
984     }
985     switch (command) {
986     case TEST_UNIT_READY:
987     case REQUEST_SENSE:
988     case INQUIRY:
989     case MODE_SENSE:
990     case MODE_SENSE_10:
991     case RESERVE:
992     case RESERVE_10:
993     case RELEASE:
994     case RELEASE_10:
995     case START_STOP:
996     case ALLOW_MEDIUM_REMOVAL:
997     case READ_CAPACITY_10:
998     case SYNCHRONIZE_CACHE:
999     case READ_TOC:
1000     case GET_CONFIGURATION:
1001     case SERVICE_ACTION_IN:
1002     case REPORT_LUNS:
1003     case VERIFY_10:
1004         rc = scsi_disk_emulate_command(r, outbuf);
1005         if (rc < 0) {
1006             return 0;
1007         }
1008
1009         r->iov.iov_len = rc;
1010         break;
1011     case READ_6:
1012     case READ_10:
1013     case READ_12:
1014     case READ_16:
1015         len = r->req.cmd.xfer / s->qdev.blocksize;
1016         DPRINTF("Read (sector %" PRId64 ", count %d)\n", r->req.cmd.lba, len);
1017         if (r->req.cmd.lba > s->max_lba)
1018             goto illegal_lba;
1019         r->sector = r->req.cmd.lba * s->cluster_size;
1020         r->sector_count = len * s->cluster_size;
1021         break;
1022     case WRITE_6:
1023     case WRITE_10:
1024     case WRITE_12:
1025     case WRITE_16:
1026     case WRITE_VERIFY_10:
1027     case WRITE_VERIFY_12:
1028     case WRITE_VERIFY_16:
1029         len = r->req.cmd.xfer / s->qdev.blocksize;
1030         DPRINTF("Write %s(sector %" PRId64 ", count %d)\n",
1031                 (command & 0xe) == 0xe ? "And Verify " : "",
1032                 r->req.cmd.lba, len);
1033         if (r->req.cmd.lba > s->max_lba)
1034             goto illegal_lba;
1035         r->sector = r->req.cmd.lba * s->cluster_size;
1036         r->sector_count = len * s->cluster_size;
1037         break;
1038     case MODE_SELECT:
1039         DPRINTF("Mode Select(6) (len %lu)\n", (long)r->req.cmd.xfer);
1040         /* We don't support mode parameter changes.
1041            Allow the mode parameter header + block descriptors only. */
1042         if (r->req.cmd.xfer > 12) {
1043             goto fail;
1044         }
1045         break;
1046     case MODE_SELECT_10:
1047         DPRINTF("Mode Select(10) (len %lu)\n", (long)r->req.cmd.xfer);
1048         /* We don't support mode parameter changes.
1049            Allow the mode parameter header + block descriptors only. */
1050         if (r->req.cmd.xfer > 16) {
1051             goto fail;
1052         }
1053         break;
1054     case SEEK_6:
1055     case SEEK_10:
1056         DPRINTF("Seek(%d) (sector %" PRId64 ")\n", command == SEEK_6 ? 6 : 10,
1057                 r->req.cmd.lba);
1058         if (r->req.cmd.lba > s->max_lba) {
1059             goto illegal_lba;
1060         }
1061         break;
1062     case WRITE_SAME_16:
1063         len = r->req.cmd.xfer / s->qdev.blocksize;
1064
1065         DPRINTF("WRITE SAME(16) (sector %" PRId64 ", count %d)\n",
1066                 r->req.cmd.lba, len);
1067
1068         if (r->req.cmd.lba > s->max_lba) {
1069             goto illegal_lba;
1070         }
1071
1072         /*
1073          * We only support WRITE SAME with the unmap bit set for now.
1074          */
1075         if (!(buf[1] & 0x8)) {
1076             goto fail;
1077         }
1078
1079         rc = bdrv_discard(s->bs, r->req.cmd.lba * s->cluster_size,
1080                           len * s->cluster_size);
1081         if (rc < 0) {
1082             /* XXX: better error code ?*/
1083             goto fail;
1084         }
1085
1086         break;
1087     default:
1088         DPRINTF("Unknown SCSI command (%2.2x)\n", buf[0]);
1089         scsi_check_condition(r, SENSE_CODE(INVALID_OPCODE));
1090         return 0;
1091     fail:
1092         scsi_check_condition(r, SENSE_CODE(INVALID_FIELD));
1093         return 0;
1094     illegal_lba:
1095         scsi_check_condition(r, SENSE_CODE(LBA_OUT_OF_RANGE));
1096         return 0;
1097     }
1098     if (r->sector_count == 0 && r->iov.iov_len == 0) {
1099         scsi_req_complete(&r->req, GOOD);
1100     }
1101     len = r->sector_count * 512 + r->iov.iov_len;
1102     if (r->req.cmd.mode == SCSI_XFER_TO_DEV) {
1103         return -len;
1104     } else {
1105         if (!r->sector_count)
1106             r->sector_count = -1;
1107         return len;
1108     }
1109 }
1110
1111 static void scsi_disk_reset(DeviceState *dev)
1112 {
1113     SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev.qdev, dev);
1114     uint64_t nb_sectors;
1115
1116     scsi_device_purge_requests(&s->qdev);
1117
1118     bdrv_get_geometry(s->bs, &nb_sectors);
1119     nb_sectors /= s->cluster_size;
1120     if (nb_sectors) {
1121         nb_sectors--;
1122     }
1123     s->max_lba = nb_sectors;
1124 }
1125
1126 static void scsi_destroy(SCSIDevice *dev)
1127 {
1128     SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
1129
1130     scsi_device_purge_requests(&s->qdev);
1131     blockdev_mark_auto_del(s->qdev.conf.bs);
1132 }
1133
1134 static int scsi_initfn(SCSIDevice *dev, uint8_t scsi_type)
1135 {
1136     SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
1137     DriveInfo *dinfo;
1138
1139     if (!s->qdev.conf.bs) {
1140         error_report("scsi-disk: drive property not set");
1141         return -1;
1142     }
1143     s->bs = s->qdev.conf.bs;
1144
1145     if (scsi_type == TYPE_DISK && !bdrv_is_inserted(s->bs)) {
1146         error_report("Device needs media, but drive is empty");
1147         return -1;
1148     }
1149
1150     if (!s->serial) {
1151         /* try to fall back to value set with legacy -drive serial=... */
1152         dinfo = drive_get_by_blockdev(s->bs);
1153         if (*dinfo->serial) {
1154             s->serial = qemu_strdup(dinfo->serial);
1155         }
1156     }
1157
1158     if (!s->version) {
1159         s->version = qemu_strdup(QEMU_VERSION);
1160     }
1161
1162     if (bdrv_is_sg(s->bs)) {
1163         error_report("scsi-disk: unwanted /dev/sg*");
1164         return -1;
1165     }
1166
1167     if (scsi_type == TYPE_ROM) {
1168         s->qdev.blocksize = 2048;
1169     } else if (scsi_type == TYPE_DISK) {
1170         s->qdev.blocksize = s->qdev.conf.logical_block_size;
1171     } else {
1172         error_report("scsi-disk: Unhandled SCSI type %02x", scsi_type);
1173         return -1;
1174     }
1175     s->cluster_size = s->qdev.blocksize / 512;
1176     s->bs->buffer_alignment = s->qdev.blocksize;
1177
1178     s->qdev.type = scsi_type;
1179     qemu_add_vm_change_state_handler(scsi_dma_restart_cb, s);
1180     bdrv_set_removable(s->bs, scsi_type == TYPE_ROM);
1181     add_boot_device_path(s->qdev.conf.bootindex, &dev->qdev, ",0");
1182     return 0;
1183 }
1184
1185 static int scsi_hd_initfn(SCSIDevice *dev)
1186 {
1187     return scsi_initfn(dev, TYPE_DISK);
1188 }
1189
1190 static int scsi_cd_initfn(SCSIDevice *dev)
1191 {
1192     return scsi_initfn(dev, TYPE_ROM);
1193 }
1194
1195 static int scsi_disk_initfn(SCSIDevice *dev)
1196 {
1197     DriveInfo *dinfo;
1198     uint8_t scsi_type;
1199
1200     if (!dev->conf.bs) {
1201         scsi_type = TYPE_DISK;  /* will die in scsi_initfn() */
1202     } else {
1203         dinfo = drive_get_by_blockdev(dev->conf.bs);
1204         scsi_type = dinfo->media_cd ? TYPE_ROM : TYPE_DISK;
1205     }
1206
1207     return scsi_initfn(dev, scsi_type);
1208 }
1209
1210 static SCSIReqOps scsi_disk_reqops = {
1211     .size         = sizeof(SCSIDiskReq),
1212     .free_req     = scsi_free_request,
1213     .send_command = scsi_send_command,
1214     .read_data    = scsi_read_data,
1215     .write_data   = scsi_write_data,
1216     .cancel_io    = scsi_cancel_io,
1217     .get_buf      = scsi_get_buf,
1218 };
1219
1220 static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag,
1221                                      uint32_t lun, void *hba_private)
1222 {
1223     SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, d);
1224     SCSIRequest *req;
1225     SCSIDiskReq *r;
1226
1227     req = scsi_req_alloc(&scsi_disk_reqops, &s->qdev, tag, lun, hba_private);
1228     r = DO_UPCAST(SCSIDiskReq, req, req);
1229     r->iov.iov_base = qemu_blockalign(s->bs, SCSI_DMA_BUF_SIZE);
1230     return req;
1231 }
1232
1233 #define DEFINE_SCSI_DISK_PROPERTIES()                           \
1234     DEFINE_BLOCK_PROPERTIES(SCSIDiskState, qdev.conf),          \
1235     DEFINE_PROP_STRING("ver",  SCSIDiskState, version),         \
1236     DEFINE_PROP_STRING("serial",  SCSIDiskState, serial)
1237
1238 static SCSIDeviceInfo scsi_disk_info[] = {
1239     {
1240         .qdev.name    = "scsi-hd",
1241         .qdev.fw_name = "disk",
1242         .qdev.desc    = "virtual SCSI disk",
1243         .qdev.size    = sizeof(SCSIDiskState),
1244         .qdev.reset   = scsi_disk_reset,
1245         .init         = scsi_hd_initfn,
1246         .destroy      = scsi_destroy,
1247         .alloc_req    = scsi_new_request,
1248         .qdev.props   = (Property[]) {
1249             DEFINE_SCSI_DISK_PROPERTIES(),
1250             DEFINE_PROP_BIT("removable", SCSIDiskState, removable, 0, false),
1251             DEFINE_PROP_END_OF_LIST(),
1252         }
1253     },{
1254         .qdev.name    = "scsi-cd",
1255         .qdev.fw_name = "disk",
1256         .qdev.desc    = "virtual SCSI CD-ROM",
1257         .qdev.size    = sizeof(SCSIDiskState),
1258         .qdev.reset   = scsi_disk_reset,
1259         .init         = scsi_cd_initfn,
1260         .destroy      = scsi_destroy,
1261         .alloc_req    = scsi_new_request,
1262         .qdev.props   = (Property[]) {
1263             DEFINE_SCSI_DISK_PROPERTIES(),
1264             DEFINE_PROP_END_OF_LIST(),
1265         },
1266     },{
1267         .qdev.name    = "scsi-disk", /* legacy -device scsi-disk */
1268         .qdev.fw_name = "disk",
1269         .qdev.desc    = "virtual SCSI disk or CD-ROM (legacy)",
1270         .qdev.size    = sizeof(SCSIDiskState),
1271         .qdev.reset   = scsi_disk_reset,
1272         .init         = scsi_disk_initfn,
1273         .destroy      = scsi_destroy,
1274         .alloc_req    = scsi_new_request,
1275         .qdev.props   = (Property[]) {
1276             DEFINE_SCSI_DISK_PROPERTIES(),
1277             DEFINE_PROP_BIT("removable", SCSIDiskState, removable, 0, false),
1278             DEFINE_PROP_END_OF_LIST(),
1279         }
1280     }
1281 };
1282
1283 static void scsi_disk_register_devices(void)
1284 {
1285     int i;
1286
1287     for (i = 0; i < ARRAY_SIZE(scsi_disk_info); i++) {
1288         scsi_qdev_register(&scsi_disk_info[i]);
1289     }
1290 }
1291 device_init(scsi_disk_register_devices)
This page took 0.099633 seconds and 4 git commands to generate.