configure: change "found" to "find"
[qemu] / hw / scsi-generic.c
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 licenced under the LGPL.
11  *
12  */
13
14 #include "qemu-common.h"
15 #include "block.h"
16 #include "scsi-disk.h"
17
18 #ifdef __linux__
19
20 //#define DEBUG_SCSI
21
22 #ifdef DEBUG_SCSI
23 #define DPRINTF(fmt, ...) \
24 do { printf("scsi-generic: " fmt , ## __VA_ARGS__); } while (0)
25 #else
26 #define DPRINTF(fmt, ...) do {} while(0)
27 #endif
28
29 #define BADF(fmt, ...) \
30 do { fprintf(stderr, "scsi-generic: " fmt , ## __VA_ARGS__); } while (0)
31
32 #include <stdio.h>
33 #include <sys/types.h>
34 #include <sys/stat.h>
35 #include <unistd.h>
36 #include <scsi/sg.h>
37 #include <scsi/scsi.h>
38
39 #define REWIND 0x01
40 #define REPORT_DENSITY_SUPPORT 0x44
41 #define LOAD_UNLOAD 0xa6
42 #define SET_CD_SPEED 0xbb
43 #define BLANK 0xa1
44
45 #define SCSI_CMD_BUF_SIZE     16
46 #define SCSI_SENSE_BUF_SIZE 96
47
48 #define SG_ERR_DRIVER_TIMEOUT 0x06
49 #define SG_ERR_DRIVER_SENSE 0x08
50
51 #ifndef MAX_UINT
52 #define MAX_UINT ((unsigned int)-1)
53 #endif
54
55 typedef struct SCSIGenericState SCSIGenericState;
56
57 typedef struct SCSIRequest {
58     BlockDriverAIOCB *aiocb;
59     struct SCSIRequest *next;
60     SCSIBus *bus;
61     SCSIGenericState *dev;
62     uint32_t tag;
63     uint8_t cmd[SCSI_CMD_BUF_SIZE];
64     int cmdlen;
65     uint8_t *buf;
66     int buflen;
67     int len;
68     sg_io_hdr_t io_header;
69 } SCSIRequest;
70
71 struct SCSIGenericState
72 {
73     SCSIDevice qdev;
74     SCSIRequest *requests;
75     DriveInfo *dinfo;
76     int type;
77     int blocksize;
78     int lun;
79     int driver_status;
80     uint8_t sensebuf[SCSI_SENSE_BUF_SIZE];
81     uint8_t senselen;
82 };
83
84 /* Global pool of SCSIRequest structures.  */
85 static SCSIRequest *free_requests = NULL;
86
87 static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag)
88 {
89     SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, d);
90     SCSIRequest *r;
91
92     if (free_requests) {
93         r = free_requests;
94         free_requests = r->next;
95     } else {
96         r = qemu_malloc(sizeof(SCSIRequest));
97         r->buf = NULL;
98         r->buflen = 0;
99     }
100     r->bus = scsi_bus_from_device(d);
101     r->dev = s;
102     r->tag = tag;
103     memset(r->cmd, 0, sizeof(r->cmd));
104     memset(&r->io_header, 0, sizeof(r->io_header));
105     r->cmdlen = 0;
106     r->len = 0;
107     r->aiocb = NULL;
108
109     /* link */
110
111     r->next = s->requests;
112     s->requests = r;
113     return r;
114 }
115
116 static void scsi_remove_request(SCSIRequest *r)
117 {
118     SCSIRequest *last;
119     SCSIGenericState *s = r->dev;
120
121     if (s->requests == r) {
122         s->requests = r->next;
123     } else {
124         last = s->requests;
125         while (last && last->next != r)
126             last = last->next;
127         if (last) {
128             last->next = r->next;
129         } else {
130             BADF("Orphaned request\n");
131         }
132     }
133     r->next = free_requests;
134     free_requests = r;
135 }
136
137 static SCSIRequest *scsi_find_request(SCSIGenericState *s, uint32_t tag)
138 {
139     SCSIRequest *r;
140
141     r = s->requests;
142     while (r && r->tag != tag)
143         r = r->next;
144
145     return r;
146 }
147
148 /* Helper function for command completion.  */
149 static void scsi_command_complete(void *opaque, int ret)
150 {
151     SCSIRequest *r = (SCSIRequest *)opaque;
152     SCSIGenericState *s = r->dev;
153     uint32_t tag;
154     int status;
155
156     s->driver_status = r->io_header.driver_status;
157     if (s->driver_status & SG_ERR_DRIVER_SENSE)
158         s->senselen = r->io_header.sb_len_wr;
159
160     if (ret != 0)
161         status = BUSY << 1;
162     else {
163         if (s->driver_status & SG_ERR_DRIVER_TIMEOUT) {
164             status = BUSY << 1;
165             BADF("Driver Timeout\n");
166         } else if (r->io_header.status)
167             status = r->io_header.status;
168         else if (s->driver_status & SG_ERR_DRIVER_SENSE)
169             status = CHECK_CONDITION << 1;
170         else
171             status = GOOD << 1;
172     }
173     DPRINTF("Command complete 0x%p tag=0x%x status=%d\n",
174             r, r->tag, status);
175     tag = r->tag;
176     scsi_remove_request(r);
177     r->bus->complete(r->bus, SCSI_REASON_DONE, tag, status);
178 }
179
180 /* Cancel a pending data transfer.  */
181 static void scsi_cancel_io(SCSIDevice *d, uint32_t tag)
182 {
183     DPRINTF("scsi_cancel_io 0x%x\n", tag);
184     SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, d);
185     SCSIRequest *r;
186     DPRINTF("Cancel tag=0x%x\n", tag);
187     r = scsi_find_request(s, tag);
188     if (r) {
189         if (r->aiocb)
190             bdrv_aio_cancel(r->aiocb);
191         r->aiocb = NULL;
192         scsi_remove_request(r);
193     }
194 }
195
196 static int execute_command(BlockDriverState *bdrv,
197                            SCSIRequest *r, int direction,
198                            BlockDriverCompletionFunc *complete)
199 {
200     r->io_header.interface_id = 'S';
201     r->io_header.dxfer_direction = direction;
202     r->io_header.dxferp = r->buf;
203     r->io_header.dxfer_len = r->buflen;
204     r->io_header.cmdp = r->cmd;
205     r->io_header.cmd_len = r->cmdlen;
206     r->io_header.mx_sb_len = sizeof(r->dev->sensebuf);
207     r->io_header.sbp = r->dev->sensebuf;
208     r->io_header.timeout = MAX_UINT;
209     r->io_header.usr_ptr = r;
210     r->io_header.flags |= SG_FLAG_DIRECT_IO;
211
212     r->aiocb = bdrv_aio_ioctl(bdrv, SG_IO, &r->io_header, complete, r);
213     if (r->aiocb == NULL) {
214         BADF("execute_command: read failed !\n");
215         return -1;
216     }
217
218     return 0;
219 }
220
221 static void scsi_read_complete(void * opaque, int ret)
222 {
223     SCSIRequest *r = (SCSIRequest *)opaque;
224     int len;
225
226     if (ret) {
227         DPRINTF("IO error\n");
228         scsi_command_complete(r, ret);
229         return;
230     }
231     len = r->io_header.dxfer_len - r->io_header.resid;
232     DPRINTF("Data ready tag=0x%x len=%d\n", r->tag, len);
233
234     r->len = -1;
235     r->bus->complete(r->bus, SCSI_REASON_DATA, r->tag, len);
236     if (len == 0)
237         scsi_command_complete(r, 0);
238 }
239
240 /* Read more data from scsi device into buffer.  */
241 static void scsi_read_data(SCSIDevice *d, uint32_t tag)
242 {
243     SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, d);
244     SCSIRequest *r;
245     int ret;
246
247     DPRINTF("scsi_read_data 0x%x\n", tag);
248     r = scsi_find_request(s, tag);
249     if (!r) {
250         BADF("Bad read tag 0x%x\n", tag);
251         /* ??? This is the wrong error.  */
252         scsi_command_complete(r, -EINVAL);
253         return;
254     }
255
256     if (r->len == -1) {
257         scsi_command_complete(r, 0);
258         return;
259     }
260
261     if (r->cmd[0] == REQUEST_SENSE && s->driver_status & SG_ERR_DRIVER_SENSE)
262     {
263         s->senselen = MIN(r->len, s->senselen);
264         memcpy(r->buf, s->sensebuf, s->senselen);
265         r->io_header.driver_status = 0;
266         r->io_header.status = 0;
267         r->io_header.dxfer_len  = s->senselen;
268         r->len = -1;
269         DPRINTF("Data ready tag=0x%x len=%d\n", r->tag, s->senselen);
270         DPRINTF("Sense: %d %d %d %d %d %d %d %d\n",
271                 r->buf[0], r->buf[1], r->buf[2], r->buf[3],
272                 r->buf[4], r->buf[5], r->buf[6], r->buf[7]);
273         r->bus->complete(r->bus, SCSI_REASON_DATA, r->tag, s->senselen);
274         return;
275     }
276
277     ret = execute_command(s->dinfo->bdrv, r, SG_DXFER_FROM_DEV, scsi_read_complete);
278     if (ret == -1) {
279         scsi_command_complete(r, -EINVAL);
280         return;
281     }
282 }
283
284 static void scsi_write_complete(void * opaque, int ret)
285 {
286     SCSIRequest *r = (SCSIRequest *)opaque;
287
288     DPRINTF("scsi_write_complete() ret = %d\n", ret);
289     if (ret) {
290         DPRINTF("IO error\n");
291         scsi_command_complete(r, ret);
292         return;
293     }
294
295     if (r->cmd[0] == MODE_SELECT && r->cmd[4] == 12 &&
296         r->dev->type == TYPE_TAPE) {
297         r->dev->blocksize = (r->buf[9] << 16) | (r->buf[10] << 8) | r->buf[11];
298         DPRINTF("block size %d\n", r->dev->blocksize);
299     }
300
301     scsi_command_complete(r, ret);
302 }
303
304 /* Write data to a scsi device.  Returns nonzero on failure.
305    The transfer may complete asynchronously.  */
306 static int scsi_write_data(SCSIDevice *d, uint32_t tag)
307 {
308     SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, d);
309     SCSIRequest *r;
310     int ret;
311
312     DPRINTF("scsi_write_data 0x%x\n", tag);
313     r = scsi_find_request(s, tag);
314     if (!r) {
315         BADF("Bad write tag 0x%x\n", tag);
316         /* ??? This is the wrong error.  */
317         scsi_command_complete(r, -EINVAL);
318         return 0;
319     }
320
321     if (r->len == 0) {
322         r->len = r->buflen;
323         r->bus->complete(r->bus, SCSI_REASON_DATA, r->tag, r->len);
324         return 0;
325     }
326
327     ret = execute_command(s->dinfo->bdrv, r, SG_DXFER_TO_DEV, scsi_write_complete);
328     if (ret == -1) {
329         scsi_command_complete(r, -EINVAL);
330         return 1;
331     }
332
333     return 0;
334 }
335
336 /* Return a pointer to the data buffer.  */
337 static uint8_t *scsi_get_buf(SCSIDevice *d, uint32_t tag)
338 {
339     SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, d);
340     SCSIRequest *r;
341     r = scsi_find_request(s, tag);
342     if (!r) {
343         BADF("Bad buffer tag 0x%x\n", tag);
344         return NULL;
345     }
346     return r->buf;
347 }
348
349 static int scsi_length(uint8_t *cmd, int blocksize, int *cmdlen, uint32_t *len)
350 {
351     switch (cmd[0] >> 5) {
352     case 0:
353         *len = cmd[4];
354         *cmdlen = 6;
355         /* length 0 means 256 blocks */
356         if (*len == 0)
357             *len = 256;
358         break;
359     case 1:
360     case 2:
361         *len = cmd[8] | (cmd[7] << 8);
362         *cmdlen = 10;
363         break;
364     case 4:
365         *len = cmd[13] | (cmd[12] << 8) | (cmd[11] << 16) | (cmd[10] << 24);
366         *cmdlen = 16;
367         break;
368     case 5:
369         *len = cmd[9] | (cmd[8] << 8) | (cmd[7] << 16) | (cmd[6] << 24);
370         *cmdlen = 12;
371         break;
372     default:
373         return -1;
374     }
375
376     switch(cmd[0]) {
377     case TEST_UNIT_READY:
378     case REZERO_UNIT:
379     case START_STOP:
380     case SEEK_6:
381     case WRITE_FILEMARKS:
382     case SPACE:
383     case ERASE:
384     case ALLOW_MEDIUM_REMOVAL:
385     case VERIFY:
386     case SEEK_10:
387     case SYNCHRONIZE_CACHE:
388     case LOCK_UNLOCK_CACHE:
389     case LOAD_UNLOAD:
390     case SET_CD_SPEED:
391     case SET_LIMITS:
392     case WRITE_LONG:
393     case MOVE_MEDIUM:
394     case UPDATE_BLOCK:
395         *len = 0;
396         break;
397     case MODE_SENSE:
398         break;
399     case WRITE_SAME:
400         *len = 1;
401         break;
402     case READ_CAPACITY:
403         *len = 8;
404         break;
405     case READ_BLOCK_LIMITS:
406         *len = 6;
407         break;
408     case READ_POSITION:
409         *len = 20;
410         break;
411     case SEND_VOLUME_TAG:
412         *len *= 40;
413         break;
414     case MEDIUM_SCAN:
415         *len *= 8;
416         break;
417     case WRITE_10:
418         cmd[1] &= ~0x08;        /* disable FUA */
419     case WRITE_VERIFY:
420     case WRITE_6:
421     case WRITE_12:
422     case WRITE_VERIFY_12:
423         *len *= blocksize;
424         break;
425     case READ_10:
426         cmd[1] &= ~0x08;        /* disable FUA */
427     case READ_6:
428     case READ_REVERSE:
429     case RECOVER_BUFFERED_DATA:
430     case READ_12:
431         *len *= blocksize;
432         break;
433     case INQUIRY:
434         *len = cmd[4] | (cmd[3] << 8);
435         break;
436     }
437     return 0;
438 }
439
440 static int scsi_stream_length(uint8_t *cmd, int blocksize, int *cmdlen, uint32_t *len)
441 {
442     switch(cmd[0]) {
443     /* stream commands */
444     case READ_6:
445     case READ_REVERSE:
446     case RECOVER_BUFFERED_DATA:
447     case WRITE_6:
448         *cmdlen = 6;
449         *len = cmd[4] | (cmd[3] << 8) | (cmd[2] << 16);
450         if (cmd[1] & 0x01) /* fixed */
451             *len *= blocksize;
452         break;
453     case REWIND:
454     case START_STOP:
455         *cmdlen = 6;
456         *len = 0;
457         cmd[1] = 0x01;  /* force IMMED, otherwise qemu waits end of command */
458         break;
459     /* generic commands */
460     default:
461         return scsi_length(cmd, blocksize, cmdlen, len);
462     }
463     return 0;
464 }
465
466 static int is_write(int command)
467 {
468     switch (command) {
469     case COPY:
470     case COPY_VERIFY:
471     case COMPARE:
472     case CHANGE_DEFINITION:
473     case LOG_SELECT:
474     case MODE_SELECT:
475     case MODE_SELECT_10:
476     case SEND_DIAGNOSTIC:
477     case WRITE_BUFFER:
478     case FORMAT_UNIT:
479     case REASSIGN_BLOCKS:
480     case RESERVE:
481     case SEARCH_EQUAL:
482     case SEARCH_HIGH:
483     case SEARCH_LOW:
484     case WRITE_6:
485     case WRITE_10:
486     case WRITE_VERIFY:
487     case UPDATE_BLOCK:
488     case WRITE_LONG:
489     case WRITE_SAME:
490     case SEARCH_HIGH_12:
491     case SEARCH_EQUAL_12:
492     case SEARCH_LOW_12:
493     case WRITE_12:
494     case WRITE_VERIFY_12:
495     case SET_WINDOW:
496     case MEDIUM_SCAN:
497     case SEND_VOLUME_TAG:
498     case WRITE_LONG_2:
499         return 1;
500     }
501     return 0;
502 }
503
504 /* Execute a scsi command.  Returns the length of the data expected by the
505    command.  This will be Positive for data transfers from the device
506    (eg. disk reads), negative for transfers to the device (eg. disk writes),
507    and zero if the command does not transfer any data.  */
508
509 static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
510                                  uint8_t *cmd, int lun)
511 {
512     SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, d);
513     uint32_t len=0;
514     int cmdlen=0;
515     SCSIRequest *r;
516     SCSIBus *bus;
517     int ret;
518
519     if (s->type == TYPE_TAPE) {
520         if (scsi_stream_length(cmd, s->blocksize, &cmdlen, &len) == -1) {
521             BADF("Unsupported command length, command %x\n", cmd[0]);
522             return 0;
523         }
524      } else {
525         if (scsi_length(cmd, s->blocksize, &cmdlen, &len) == -1) {
526             BADF("Unsupported command length, command %x\n", cmd[0]);
527             return 0;
528         }
529     }
530
531     DPRINTF("Command: lun=%d tag=0x%x data=0x%02x len %d\n", lun, tag,
532             cmd[0], len);
533
534     if (cmd[0] != REQUEST_SENSE &&
535         (lun != s->lun || (cmd[1] >> 5) != s->lun)) {
536         DPRINTF("Unimplemented LUN %d\n", lun ? lun : cmd[1] >> 5);
537
538         s->sensebuf[0] = 0x70;
539         s->sensebuf[1] = 0x00;
540         s->sensebuf[2] = ILLEGAL_REQUEST;
541         s->sensebuf[3] = 0x00;
542         s->sensebuf[4] = 0x00;
543         s->sensebuf[5] = 0x00;
544         s->sensebuf[6] = 0x00;
545         s->senselen = 7;
546         s->driver_status = SG_ERR_DRIVER_SENSE;
547         bus = scsi_bus_from_device(d);
548         bus->complete(bus, SCSI_REASON_DONE, tag, CHECK_CONDITION << 1);
549         return 0;
550     }
551
552     r = scsi_find_request(s, tag);
553     if (r) {
554         BADF("Tag 0x%x already in use %p\n", tag, r);
555         scsi_cancel_io(d, tag);
556     }
557     r = scsi_new_request(d, tag);
558
559     memcpy(r->cmd, cmd, cmdlen);
560     r->cmdlen = cmdlen;
561
562     if (len == 0) {
563         if (r->buf != NULL)
564             free(r->buf);
565         r->buflen = 0;
566         r->buf = NULL;
567         ret = execute_command(s->dinfo->bdrv, r, SG_DXFER_NONE, scsi_command_complete);
568         if (ret == -1) {
569             scsi_command_complete(r, -EINVAL);
570             return 0;
571         }
572         return 0;
573     }
574
575     if (r->buflen != len) {
576         if (r->buf != NULL)
577             free(r->buf);
578         r->buf = qemu_malloc(len);
579         r->buflen = len;
580     }
581
582     memset(r->buf, 0, r->buflen);
583     r->len = len;
584     if (is_write(cmd[0])) {
585         r->len = 0;
586         return -len;
587     }
588
589     return len;
590 }
591
592 static int get_blocksize(BlockDriverState *bdrv)
593 {
594     uint8_t cmd[10];
595     uint8_t buf[8];
596     uint8_t sensebuf[8];
597     sg_io_hdr_t io_header;
598     int ret;
599
600     memset(cmd, 0, sizeof(cmd));
601     memset(buf, 0, sizeof(buf));
602     cmd[0] = READ_CAPACITY;
603
604     memset(&io_header, 0, sizeof(io_header));
605     io_header.interface_id = 'S';
606     io_header.dxfer_direction = SG_DXFER_FROM_DEV;
607     io_header.dxfer_len = sizeof(buf);
608     io_header.dxferp = buf;
609     io_header.cmdp = cmd;
610     io_header.cmd_len = sizeof(cmd);
611     io_header.mx_sb_len = sizeof(sensebuf);
612     io_header.sbp = sensebuf;
613     io_header.timeout = 6000; /* XXX */
614
615     ret = bdrv_ioctl(bdrv, SG_IO, &io_header);
616     if (ret < 0)
617         return -1;
618
619     return (buf[4] << 24) | (buf[5] << 16) | (buf[6] << 8) | buf[7];
620 }
621
622 static int get_stream_blocksize(BlockDriverState *bdrv)
623 {
624     uint8_t cmd[6];
625     uint8_t buf[12];
626     uint8_t sensebuf[8];
627     sg_io_hdr_t io_header;
628     int ret;
629
630     memset(cmd, 0, sizeof(cmd));
631     memset(buf, 0, sizeof(buf));
632     cmd[0] = MODE_SENSE;
633     cmd[4] = sizeof(buf);
634
635     memset(&io_header, 0, sizeof(io_header));
636     io_header.interface_id = 'S';
637     io_header.dxfer_direction = SG_DXFER_FROM_DEV;
638     io_header.dxfer_len = sizeof(buf);
639     io_header.dxferp = buf;
640     io_header.cmdp = cmd;
641     io_header.cmd_len = sizeof(cmd);
642     io_header.mx_sb_len = sizeof(sensebuf);
643     io_header.sbp = sensebuf;
644     io_header.timeout = 6000; /* XXX */
645
646     ret = bdrv_ioctl(bdrv, SG_IO, &io_header);
647     if (ret < 0)
648         return -1;
649
650     return (buf[9] << 16) | (buf[10] << 8) | buf[11];
651 }
652
653 static void scsi_destroy(SCSIDevice *d)
654 {
655     SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, d);
656     SCSIRequest *r, *n;
657
658     r = s->requests;
659     while (r) {
660         n = r->next;
661         qemu_free(r);
662         r = n;
663     }
664
665     r = free_requests;
666     while (r) {
667         n = r->next;
668         qemu_free(r);
669         r = n;
670     }
671
672     qemu_free(d);
673 }
674
675 static int scsi_generic_initfn(SCSIDevice *dev)
676 {
677     SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, dev);
678     int sg_version;
679     struct sg_scsi_id scsiid;
680
681     if (!s->dinfo || !s->dinfo->bdrv) {
682         qemu_error("scsi-generic: drive property not set\n");
683         return -1;
684     }
685
686     /* check we are really using a /dev/sg* file */
687     if (!bdrv_is_sg(s->dinfo->bdrv)) {
688         qemu_error("scsi-generic: not /dev/sg*\n");
689         return -1;
690     }
691
692     /* check we are using a driver managing SG_IO (version 3 and after */
693     if (bdrv_ioctl(s->dinfo->bdrv, SG_GET_VERSION_NUM, &sg_version) < 0 ||
694         sg_version < 30000) {
695         qemu_error("scsi-generic: scsi generic interface too old\n");
696         return -1;
697     }
698
699     /* get LUN of the /dev/sg? */
700     if (bdrv_ioctl(s->dinfo->bdrv, SG_GET_SCSI_ID, &scsiid)) {
701         qemu_error("scsi-generic: SG_GET_SCSI_ID ioctl failed\n");
702         return -1;
703     }
704
705     /* define device state */
706     s->lun = scsiid.lun;
707     DPRINTF("LUN %d\n", s->lun);
708     s->type = scsiid.scsi_type;
709     DPRINTF("device type %d\n", s->type);
710     if (s->type == TYPE_TAPE) {
711         s->blocksize = get_stream_blocksize(s->dinfo->bdrv);
712         if (s->blocksize == -1)
713             s->blocksize = 0;
714     } else {
715         s->blocksize = get_blocksize(s->dinfo->bdrv);
716         /* removable media returns 0 if not present */
717         if (s->blocksize <= 0) {
718             if (s->type == TYPE_ROM || s->type  == TYPE_WORM)
719                 s->blocksize = 2048;
720             else
721                 s->blocksize = 512;
722         }
723     }
724     DPRINTF("block size %d\n", s->blocksize);
725     s->driver_status = 0;
726     memset(s->sensebuf, 0, sizeof(s->sensebuf));
727     return 0;
728 }
729
730 static SCSIDeviceInfo scsi_generic_info = {
731     .qdev.name    = "scsi-generic",
732     .qdev.desc    = "pass through generic scsi device (/dev/sg*)",
733     .qdev.size    = sizeof(SCSIGenericState),
734     .init         = scsi_generic_initfn,
735     .destroy      = scsi_destroy,
736     .send_command = scsi_send_command,
737     .read_data    = scsi_read_data,
738     .write_data   = scsi_write_data,
739     .cancel_io    = scsi_cancel_io,
740     .get_buf      = scsi_get_buf,
741     .qdev.props   = (Property[]) {
742         DEFINE_PROP_DRIVE("drive", SCSIGenericState, dinfo),
743         DEFINE_PROP_END_OF_LIST(),
744     },
745 };
746
747 static void scsi_generic_register_devices(void)
748 {
749     scsi_qdev_register(&scsi_generic_info);
750 }
751 device_init(scsi_generic_register_devices)
752
753 #endif /* __linux__ */