xref: /openbmc/qemu/hw/scsi/scsi-generic.c (revision 8f3cd250)
1 /*
2  * Generic SCSI Device support
3  *
4  * Copyright (c) 2007 Bull S.A.S.
5  * Based on code by Paul Brook
6  * Based on code by Fabrice Bellard
7  *
8  * Written by Laurent Vivier <Laurent.Vivier@bull.net>
9  *
10  * This code is licensed under the LGPL.
11  *
12  */
13 
14 #include "qemu/osdep.h"
15 #include "qapi/error.h"
16 #include "qemu-common.h"
17 #include "qemu/error-report.h"
18 #include "hw/scsi/scsi.h"
19 #include "sysemu/block-backend.h"
20 
21 #ifdef __linux__
22 
23 //#define DEBUG_SCSI
24 
25 #ifdef DEBUG_SCSI
26 #define DPRINTF(fmt, ...) \
27 do { printf("scsi-generic: " fmt , ## __VA_ARGS__); } while (0)
28 #else
29 #define DPRINTF(fmt, ...) do {} while(0)
30 #endif
31 
32 #define BADF(fmt, ...) \
33 do { fprintf(stderr, "scsi-generic: " fmt , ## __VA_ARGS__); } while (0)
34 
35 #include <scsi/sg.h>
36 #include "scsi/constants.h"
37 
38 #ifndef MAX_UINT
39 #define MAX_UINT ((unsigned int)-1)
40 #endif
41 
42 typedef struct SCSIGenericReq {
43     SCSIRequest req;
44     uint8_t *buf;
45     int buflen;
46     int len;
47     sg_io_hdr_t io_header;
48 } SCSIGenericReq;
49 
50 static void scsi_generic_save_request(QEMUFile *f, SCSIRequest *req)
51 {
52     SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
53 
54     qemu_put_sbe32s(f, &r->buflen);
55     if (r->buflen && r->req.cmd.mode == SCSI_XFER_TO_DEV) {
56         assert(!r->req.sg);
57         qemu_put_buffer(f, r->buf, r->req.cmd.xfer);
58     }
59 }
60 
61 static void scsi_generic_load_request(QEMUFile *f, SCSIRequest *req)
62 {
63     SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
64 
65     qemu_get_sbe32s(f, &r->buflen);
66     if (r->buflen && r->req.cmd.mode == SCSI_XFER_TO_DEV) {
67         assert(!r->req.sg);
68         qemu_get_buffer(f, r->buf, r->req.cmd.xfer);
69     }
70 }
71 
72 static void scsi_free_request(SCSIRequest *req)
73 {
74     SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
75 
76     g_free(r->buf);
77 }
78 
79 /* Helper function for command completion.  */
80 static void scsi_command_complete_noio(SCSIGenericReq *r, int ret)
81 {
82     int status;
83     SCSISense sense;
84 
85     assert(r->req.aiocb == NULL);
86 
87     if (r->req.io_canceled) {
88         scsi_req_cancel_complete(&r->req);
89         goto done;
90     }
91     status = sg_io_sense_from_errno(-ret, &r->io_header, &sense);
92     if (status == CHECK_CONDITION) {
93         if (r->io_header.driver_status & SG_ERR_DRIVER_SENSE) {
94             r->req.sense_len = r->io_header.sb_len_wr;
95         } else {
96             scsi_req_build_sense(&r->req, sense);
97         }
98     }
99 
100     DPRINTF("Command complete 0x%p tag=0x%x status=%d\n",
101             r, r->req.tag, status);
102 
103     scsi_req_complete(&r->req, status);
104 done:
105     scsi_req_unref(&r->req);
106 }
107 
108 static void scsi_command_complete(void *opaque, int ret)
109 {
110     SCSIGenericReq *r = (SCSIGenericReq *)opaque;
111     SCSIDevice *s = r->req.dev;
112 
113     assert(r->req.aiocb != NULL);
114     r->req.aiocb = NULL;
115 
116     aio_context_acquire(blk_get_aio_context(s->conf.blk));
117     scsi_command_complete_noio(r, ret);
118     aio_context_release(blk_get_aio_context(s->conf.blk));
119 }
120 
121 static int execute_command(BlockBackend *blk,
122                            SCSIGenericReq *r, int direction,
123                            BlockCompletionFunc *complete)
124 {
125     r->io_header.interface_id = 'S';
126     r->io_header.dxfer_direction = direction;
127     r->io_header.dxferp = r->buf;
128     r->io_header.dxfer_len = r->buflen;
129     r->io_header.cmdp = r->req.cmd.buf;
130     r->io_header.cmd_len = r->req.cmd.len;
131     r->io_header.mx_sb_len = sizeof(r->req.sense);
132     r->io_header.sbp = r->req.sense;
133     r->io_header.timeout = MAX_UINT;
134     r->io_header.usr_ptr = r;
135     r->io_header.flags |= SG_FLAG_DIRECT_IO;
136 
137     r->req.aiocb = blk_aio_ioctl(blk, SG_IO, &r->io_header, complete, r);
138     if (r->req.aiocb == NULL) {
139         return -EIO;
140     }
141 
142     return 0;
143 }
144 
145 static void scsi_handle_inquiry_reply(SCSIGenericReq *r, SCSIDevice *s)
146 {
147     uint8_t page, page_len;
148 
149     /*
150      *  EVPD set to zero returns the standard INQUIRY data.
151      *
152      *  Check if scsi_version is unset (-1) to avoid re-defining it
153      *  each time an INQUIRY with standard data is received.
154      *  scsi_version is initialized with -1 in scsi_generic_reset
155      *  and scsi_disk_reset, making sure that we'll set the
156      *  scsi_version after a reset. If the version field of the
157      *  INQUIRY response somehow changes after a guest reboot,
158      *  we'll be able to keep track of it.
159      *
160      *  On SCSI-2 and older, first 3 bits of byte 2 is the
161      *  ANSI-approved version, while on later versions the
162      *  whole byte 2 contains the version. Check if we're dealing
163      *  with a newer version and, in that case, assign the
164      *  whole byte.
165      */
166     if (s->scsi_version == -1 && !(r->req.cmd.buf[1] & 0x01)) {
167         s->scsi_version = r->buf[2] & 0x07;
168         if (s->scsi_version > 2) {
169             s->scsi_version = r->buf[2];
170         }
171     }
172 
173     if (s->type == TYPE_DISK && (r->req.cmd.buf[1] & 0x01)) {
174         page = r->req.cmd.buf[2];
175         if (page == 0xb0) {
176             uint32_t max_transfer =
177                 blk_get_max_transfer(s->conf.blk) / s->blocksize;
178 
179             assert(max_transfer);
180             stl_be_p(&r->buf[8], max_transfer);
181             /* Also take care of the opt xfer len. */
182             stl_be_p(&r->buf[12],
183                     MIN_NON_ZERO(max_transfer, ldl_be_p(&r->buf[12])));
184         } else if (page == 0x00 && s->needs_vpd_bl_emulation) {
185             /*
186              * Now we're capable of supplying the VPD Block Limits
187              * response if the hardware can't. Add it in the INQUIRY
188              * Supported VPD pages response in case we are using the
189              * emulation for this device.
190              *
191              * This way, the guest kernel will be aware of the support
192              * and will use it to proper setup the SCSI device.
193              */
194             page_len = r->buf[3];
195             r->buf[page_len + 4] = 0xb0;
196             r->buf[3] = ++page_len;
197         }
198     }
199 }
200 
201 static int scsi_emulate_block_limits(SCSIGenericReq *r)
202 {
203     r->buflen = scsi_disk_emulate_vpd_page(&r->req, r->buf);
204     r->io_header.sb_len_wr = 0;
205 
206     /*
207     * We have valid contents in the reply buffer but the
208     * io_header can report a sense error coming from
209     * the hardware in scsi_command_complete_noio. Clean
210     * up the io_header to avoid reporting it.
211     */
212     r->io_header.driver_status = 0;
213     r->io_header.status = 0;
214 
215     return r->buflen;
216 }
217 
218 static void scsi_read_complete(void * opaque, int ret)
219 {
220     SCSIGenericReq *r = (SCSIGenericReq *)opaque;
221     SCSIDevice *s = r->req.dev;
222     SCSISense sense;
223     int len;
224 
225     assert(r->req.aiocb != NULL);
226     r->req.aiocb = NULL;
227 
228     aio_context_acquire(blk_get_aio_context(s->conf.blk));
229 
230     if (ret || r->req.io_canceled) {
231         scsi_command_complete_noio(r, ret);
232         goto done;
233     }
234 
235     len = r->io_header.dxfer_len - r->io_header.resid;
236     DPRINTF("Data ready tag=0x%x len=%d\n", r->req.tag, len);
237 
238     r->len = -1;
239 
240     /*
241      * Check if this is a VPD Block Limits request that
242      * resulted in sense error but would need emulation.
243      * In this case, emulate a valid VPD response.
244      */
245     if (s->needs_vpd_bl_emulation) {
246         int is_vpd_bl = r->req.cmd.buf[0] == INQUIRY &&
247                          r->req.cmd.buf[1] & 0x01 &&
248                          r->req.cmd.buf[2] == 0xb0;
249 
250         if (is_vpd_bl && sg_io_sense_from_errno(-ret, &r->io_header, &sense)) {
251             len = scsi_emulate_block_limits(r);
252             /*
253              * No need to let scsi_read_complete go on and handle an
254              * INQUIRY VPD BL request we created manually.
255              */
256             goto req_complete;
257         }
258     }
259 
260     if (len == 0) {
261         scsi_command_complete_noio(r, 0);
262         goto done;
263     }
264 
265     /* Snoop READ CAPACITY output to set the blocksize.  */
266     if (r->req.cmd.buf[0] == READ_CAPACITY_10 &&
267         (ldl_be_p(&r->buf[0]) != 0xffffffffU || s->max_lba == 0)) {
268         s->blocksize = ldl_be_p(&r->buf[4]);
269         s->max_lba = ldl_be_p(&r->buf[0]) & 0xffffffffULL;
270     } else if (r->req.cmd.buf[0] == SERVICE_ACTION_IN_16 &&
271                (r->req.cmd.buf[1] & 31) == SAI_READ_CAPACITY_16) {
272         s->blocksize = ldl_be_p(&r->buf[8]);
273         s->max_lba = ldq_be_p(&r->buf[0]);
274     }
275     blk_set_guest_block_size(s->conf.blk, s->blocksize);
276 
277     /* Patch MODE SENSE device specific parameters if the BDS is opened
278      * readonly.
279      */
280     if ((s->type == TYPE_DISK || s->type == TYPE_TAPE) &&
281         blk_is_read_only(s->conf.blk) &&
282         (r->req.cmd.buf[0] == MODE_SENSE ||
283          r->req.cmd.buf[0] == MODE_SENSE_10) &&
284         (r->req.cmd.buf[1] & 0x8) == 0) {
285         if (r->req.cmd.buf[0] == MODE_SENSE) {
286             r->buf[2] |= 0x80;
287         } else  {
288             r->buf[3] |= 0x80;
289         }
290     }
291     if (r->req.cmd.buf[0] == INQUIRY) {
292         scsi_handle_inquiry_reply(r, s);
293     }
294 
295 req_complete:
296     scsi_req_data(&r->req, len);
297     scsi_req_unref(&r->req);
298 
299 done:
300     aio_context_release(blk_get_aio_context(s->conf.blk));
301 }
302 
303 /* Read more data from scsi device into buffer.  */
304 static void scsi_read_data(SCSIRequest *req)
305 {
306     SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
307     SCSIDevice *s = r->req.dev;
308     int ret;
309 
310     DPRINTF("scsi_read_data tag=0x%x\n", req->tag);
311 
312     /* The request is used as the AIO opaque value, so add a ref.  */
313     scsi_req_ref(&r->req);
314     if (r->len == -1) {
315         scsi_command_complete_noio(r, 0);
316         return;
317     }
318 
319     ret = execute_command(s->conf.blk, r, SG_DXFER_FROM_DEV,
320                           scsi_read_complete);
321     if (ret < 0) {
322         scsi_command_complete_noio(r, ret);
323     }
324 }
325 
326 static void scsi_write_complete(void * opaque, int ret)
327 {
328     SCSIGenericReq *r = (SCSIGenericReq *)opaque;
329     SCSIDevice *s = r->req.dev;
330 
331     DPRINTF("scsi_write_complete() ret = %d\n", ret);
332 
333     assert(r->req.aiocb != NULL);
334     r->req.aiocb = NULL;
335 
336     aio_context_acquire(blk_get_aio_context(s->conf.blk));
337 
338     if (ret || r->req.io_canceled) {
339         scsi_command_complete_noio(r, ret);
340         goto done;
341     }
342 
343     if (r->req.cmd.buf[0] == MODE_SELECT && r->req.cmd.buf[4] == 12 &&
344         s->type == TYPE_TAPE) {
345         s->blocksize = (r->buf[9] << 16) | (r->buf[10] << 8) | r->buf[11];
346         DPRINTF("block size %d\n", s->blocksize);
347     }
348 
349     scsi_command_complete_noio(r, ret);
350 
351 done:
352     aio_context_release(blk_get_aio_context(s->conf.blk));
353 }
354 
355 /* Write data to a scsi device.  Returns nonzero on failure.
356    The transfer may complete asynchronously.  */
357 static void scsi_write_data(SCSIRequest *req)
358 {
359     SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
360     SCSIDevice *s = r->req.dev;
361     int ret;
362 
363     DPRINTF("scsi_write_data tag=0x%x\n", req->tag);
364     if (r->len == 0) {
365         r->len = r->buflen;
366         scsi_req_data(&r->req, r->len);
367         return;
368     }
369 
370     /* The request is used as the AIO opaque value, so add a ref.  */
371     scsi_req_ref(&r->req);
372     ret = execute_command(s->conf.blk, r, SG_DXFER_TO_DEV, scsi_write_complete);
373     if (ret < 0) {
374         scsi_command_complete_noio(r, ret);
375     }
376 }
377 
378 /* Return a pointer to the data buffer.  */
379 static uint8_t *scsi_get_buf(SCSIRequest *req)
380 {
381     SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
382 
383     return r->buf;
384 }
385 
386 /* Execute a scsi command.  Returns the length of the data expected by the
387    command.  This will be Positive for data transfers from the device
388    (eg. disk reads), negative for transfers to the device (eg. disk writes),
389    and zero if the command does not transfer any data.  */
390 
391 static int32_t scsi_send_command(SCSIRequest *req, uint8_t *cmd)
392 {
393     SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
394     SCSIDevice *s = r->req.dev;
395     int ret;
396 
397 #ifdef DEBUG_SCSI
398     DPRINTF("Command: data=0x%02x", cmd[0]);
399     {
400         int i;
401         for (i = 1; i < r->req.cmd.len; i++) {
402             printf(" 0x%02x", cmd[i]);
403         }
404         printf("\n");
405     }
406 #endif
407 
408     if (r->req.cmd.xfer == 0) {
409         g_free(r->buf);
410         r->buflen = 0;
411         r->buf = NULL;
412         /* The request is used as the AIO opaque value, so add a ref.  */
413         scsi_req_ref(&r->req);
414         ret = execute_command(s->conf.blk, r, SG_DXFER_NONE,
415                               scsi_command_complete);
416         if (ret < 0) {
417             scsi_command_complete_noio(r, ret);
418             return 0;
419         }
420         return 0;
421     }
422 
423     if (r->buflen != r->req.cmd.xfer) {
424         g_free(r->buf);
425         r->buf = g_malloc(r->req.cmd.xfer);
426         r->buflen = r->req.cmd.xfer;
427     }
428 
429     memset(r->buf, 0, r->buflen);
430     r->len = r->req.cmd.xfer;
431     if (r->req.cmd.mode == SCSI_XFER_TO_DEV) {
432         r->len = 0;
433         return -r->req.cmd.xfer;
434     } else {
435         return r->req.cmd.xfer;
436     }
437 }
438 
439 static int read_naa_id(const uint8_t *p, uint64_t *p_wwn)
440 {
441     int i;
442 
443     if ((p[1] & 0xF) == 3) {
444         /* NAA designator type */
445         if (p[3] != 8) {
446             return -EINVAL;
447         }
448         *p_wwn = ldq_be_p(p + 4);
449         return 0;
450     }
451 
452     if ((p[1] & 0xF) == 8) {
453         /* SCSI name string designator type */
454         if (p[3] < 20 || memcmp(&p[4], "naa.", 4)) {
455             return -EINVAL;
456         }
457         if (p[3] > 20 && p[24] != ',') {
458             return -EINVAL;
459         }
460         *p_wwn = 0;
461         for (i = 8; i < 24; i++) {
462             char c = qemu_toupper(p[i]);
463             c -= (c >= '0' && c <= '9' ? '0' : 'A' - 10);
464             *p_wwn = (*p_wwn << 4) | c;
465         }
466         return 0;
467     }
468 
469     return -EINVAL;
470 }
471 
472 int scsi_SG_IO_FROM_DEV(BlockBackend *blk, uint8_t *cmd, uint8_t cmd_size,
473                         uint8_t *buf, uint8_t buf_size)
474 {
475     sg_io_hdr_t io_header;
476     uint8_t sensebuf[8];
477     int ret;
478 
479     memset(&io_header, 0, sizeof(io_header));
480     io_header.interface_id = 'S';
481     io_header.dxfer_direction = SG_DXFER_FROM_DEV;
482     io_header.dxfer_len = buf_size;
483     io_header.dxferp = buf;
484     io_header.cmdp = cmd;
485     io_header.cmd_len = cmd_size;
486     io_header.mx_sb_len = sizeof(sensebuf);
487     io_header.sbp = sensebuf;
488     io_header.timeout = 6000; /* XXX */
489 
490     ret = blk_ioctl(blk, SG_IO, &io_header);
491     if (ret < 0 || io_header.driver_status || io_header.host_status) {
492         return -1;
493     }
494     return 0;
495 }
496 
497 /*
498  * Executes an INQUIRY request with EVPD set to retrieve the
499  * available VPD pages of the device. If the device does
500  * not support the Block Limits page (page 0xb0), set
501  * the needs_vpd_bl_emulation flag for future use.
502  */
503 static void scsi_generic_set_vpd_bl_emulation(SCSIDevice *s)
504 {
505     uint8_t cmd[6];
506     uint8_t buf[250];
507     uint8_t page_len;
508     int ret, i;
509 
510     memset(cmd, 0, sizeof(cmd));
511     memset(buf, 0, sizeof(buf));
512     cmd[0] = INQUIRY;
513     cmd[1] = 1;
514     cmd[2] = 0x00;
515     cmd[4] = sizeof(buf);
516 
517     ret = scsi_SG_IO_FROM_DEV(s->conf.blk, cmd, sizeof(cmd),
518                               buf, sizeof(buf));
519     if (ret < 0) {
520         /*
521          * Do not assume anything if we can't retrieve the
522          * INQUIRY response to assert the VPD Block Limits
523          * support.
524          */
525         s->needs_vpd_bl_emulation = false;
526         return;
527     }
528 
529     page_len = buf[3];
530     for (i = 4; i < page_len + 4; i++) {
531         if (buf[i] == 0xb0) {
532             s->needs_vpd_bl_emulation = false;
533             return;
534         }
535     }
536     s->needs_vpd_bl_emulation = true;
537 }
538 
539 static void scsi_generic_read_device_identification(SCSIDevice *s)
540 {
541     uint8_t cmd[6];
542     uint8_t buf[250];
543     int ret;
544     int i, len;
545 
546     memset(cmd, 0, sizeof(cmd));
547     memset(buf, 0, sizeof(buf));
548     cmd[0] = INQUIRY;
549     cmd[1] = 1;
550     cmd[2] = 0x83;
551     cmd[4] = sizeof(buf);
552 
553     ret = scsi_SG_IO_FROM_DEV(s->conf.blk, cmd, sizeof(cmd),
554                               buf, sizeof(buf));
555     if (ret < 0) {
556         return;
557     }
558 
559     len = MIN((buf[2] << 8) | buf[3], sizeof(buf) - 4);
560     for (i = 0; i + 3 <= len; ) {
561         const uint8_t *p = &buf[i + 4];
562         uint64_t wwn;
563 
564         if (i + (p[3] + 4) > len) {
565             break;
566         }
567 
568         if ((p[1] & 0x10) == 0) {
569             /* Associated with the logical unit */
570             if (read_naa_id(p, &wwn) == 0) {
571                 s->wwn = wwn;
572             }
573         } else if ((p[1] & 0x10) == 0x10) {
574             /* Associated with the target port */
575             if (read_naa_id(p, &wwn) == 0) {
576                 s->port_wwn = wwn;
577             }
578         }
579 
580         i += p[3] + 4;
581     }
582 }
583 
584 void scsi_generic_read_device_inquiry(SCSIDevice *s)
585 {
586     scsi_generic_read_device_identification(s);
587     if (s->type == TYPE_DISK) {
588         scsi_generic_set_vpd_bl_emulation(s);
589     } else {
590         s->needs_vpd_bl_emulation = false;
591     }
592 }
593 
594 static int get_stream_blocksize(BlockBackend *blk)
595 {
596     uint8_t cmd[6];
597     uint8_t buf[12];
598     int ret;
599 
600     memset(cmd, 0, sizeof(cmd));
601     memset(buf, 0, sizeof(buf));
602     cmd[0] = MODE_SENSE;
603     cmd[4] = sizeof(buf);
604 
605     ret = scsi_SG_IO_FROM_DEV(blk, cmd, sizeof(cmd), buf, sizeof(buf));
606     if (ret < 0) {
607         return -1;
608     }
609 
610     return (buf[9] << 16) | (buf[10] << 8) | buf[11];
611 }
612 
613 static void scsi_generic_reset(DeviceState *dev)
614 {
615     SCSIDevice *s = SCSI_DEVICE(dev);
616 
617     s->scsi_version = s->default_scsi_version;
618     scsi_device_purge_requests(s, SENSE_CODE(RESET));
619 }
620 
621 static void scsi_generic_realize(SCSIDevice *s, Error **errp)
622 {
623     int rc;
624     int sg_version;
625     struct sg_scsi_id scsiid;
626 
627     if (!s->conf.blk) {
628         error_setg(errp, "drive property not set");
629         return;
630     }
631 
632     if (blk_get_on_error(s->conf.blk, 0) != BLOCKDEV_ON_ERROR_ENOSPC) {
633         error_setg(errp, "Device doesn't support drive option werror");
634         return;
635     }
636     if (blk_get_on_error(s->conf.blk, 1) != BLOCKDEV_ON_ERROR_REPORT) {
637         error_setg(errp, "Device doesn't support drive option rerror");
638         return;
639     }
640 
641     /* check we are using a driver managing SG_IO (version 3 and after */
642     rc = blk_ioctl(s->conf.blk, SG_GET_VERSION_NUM, &sg_version);
643     if (rc < 0) {
644         error_setg_errno(errp, -rc, "cannot get SG_IO version number");
645         if (rc != -EPERM) {
646             error_append_hint(errp, "Is this a SCSI device?\n");
647         }
648         return;
649     }
650     if (sg_version < 30000) {
651         error_setg(errp, "scsi generic interface too old");
652         return;
653     }
654 
655     /* get LUN of the /dev/sg? */
656     if (blk_ioctl(s->conf.blk, SG_GET_SCSI_ID, &scsiid)) {
657         error_setg(errp, "SG_GET_SCSI_ID ioctl failed");
658         return;
659     }
660     if (!blkconf_apply_backend_options(&s->conf,
661                                        blk_is_read_only(s->conf.blk),
662                                        true, errp)) {
663         return;
664     }
665 
666     /* define device state */
667     s->type = scsiid.scsi_type;
668     DPRINTF("device type %d\n", s->type);
669 
670     switch (s->type) {
671     case TYPE_TAPE:
672         s->blocksize = get_stream_blocksize(s->conf.blk);
673         if (s->blocksize == -1) {
674             s->blocksize = 0;
675         }
676         break;
677 
678         /* Make a guess for block devices, we'll fix it when the guest sends.
679          * READ CAPACITY.  If they don't, they likely would assume these sizes
680          * anyway. (TODO: they could also send MODE SENSE).
681          */
682     case TYPE_ROM:
683     case TYPE_WORM:
684         s->blocksize = 2048;
685         break;
686     default:
687         s->blocksize = 512;
688         break;
689     }
690 
691     DPRINTF("block size %d\n", s->blocksize);
692 
693     /* Only used by scsi-block, but initialize it nevertheless to be clean.  */
694     s->default_scsi_version = -1;
695     scsi_generic_read_device_inquiry(s);
696 }
697 
698 const SCSIReqOps scsi_generic_req_ops = {
699     .size         = sizeof(SCSIGenericReq),
700     .free_req     = scsi_free_request,
701     .send_command = scsi_send_command,
702     .read_data    = scsi_read_data,
703     .write_data   = scsi_write_data,
704     .get_buf      = scsi_get_buf,
705     .load_request = scsi_generic_load_request,
706     .save_request = scsi_generic_save_request,
707 };
708 
709 static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun,
710                                      uint8_t *buf, void *hba_private)
711 {
712     return scsi_req_alloc(&scsi_generic_req_ops, d, tag, lun, hba_private);
713 }
714 
715 static Property scsi_generic_properties[] = {
716     DEFINE_PROP_DRIVE("drive", SCSIDevice, conf.blk),
717     DEFINE_PROP_BOOL("share-rw", SCSIDevice, conf.share_rw, false),
718     DEFINE_PROP_END_OF_LIST(),
719 };
720 
721 static int scsi_generic_parse_cdb(SCSIDevice *dev, SCSICommand *cmd,
722                                   uint8_t *buf, void *hba_private)
723 {
724     return scsi_bus_parse_cdb(dev, cmd, buf, hba_private);
725 }
726 
727 static void scsi_generic_class_initfn(ObjectClass *klass, void *data)
728 {
729     DeviceClass *dc = DEVICE_CLASS(klass);
730     SCSIDeviceClass *sc = SCSI_DEVICE_CLASS(klass);
731 
732     sc->realize      = scsi_generic_realize;
733     sc->alloc_req    = scsi_new_request;
734     sc->parse_cdb    = scsi_generic_parse_cdb;
735     dc->fw_name = "disk";
736     dc->desc = "pass through generic scsi device (/dev/sg*)";
737     dc->reset = scsi_generic_reset;
738     dc->props = scsi_generic_properties;
739     dc->vmsd  = &vmstate_scsi_device;
740 }
741 
742 static const TypeInfo scsi_generic_info = {
743     .name          = "scsi-generic",
744     .parent        = TYPE_SCSI_DEVICE,
745     .instance_size = sizeof(SCSIDevice),
746     .class_init    = scsi_generic_class_initfn,
747 };
748 
749 static void scsi_generic_register_types(void)
750 {
751     type_register_static(&scsi_generic_info);
752 }
753 
754 type_init(scsi_generic_register_types)
755 
756 #endif /* __linux__ */
757