2 * Generic SCSI Device support
4 * Copyright (c) 2007 Bull S.A.S.
5 * Based on code by Paul Brook
6 * Based on code by Fabrice Bellard
8 * Written by Laurent Vivier <Laurent.Vivier@bull.net>
10 * This code is licenced under the LGPL.
14 #include "qemu-common.h"
16 #include "scsi-disk.h"
20 SCSIDevice
*scsi_generic_init(BlockDriverState
*bdrv
, int tcq
,
21 scsi_completionfn completion
, void *opaque
)
31 #define DPRINTF(fmt, args...) \
32 do { printf("scsi-generic: " fmt , ##args); } while (0)
34 #define DPRINTF(fmt, args...) do {} while(0)
37 #define BADF(fmt, args...) \
38 do { fprintf(stderr, "scsi-generic: " fmt , ##args); } while (0)
41 #include <sys/types.h>
45 #include <scsi/scsi.h>
48 #define REPORT_DENSITY_SUPPORT 0x44
49 #define LOAD_UNLOAD 0xa6
50 #define SET_CD_SPEED 0xbb
53 #define SCSI_CMD_BUF_SIZE 16
54 #define SCSI_SENSE_BUF_SIZE 96
56 #define SG_ERR_DRIVER_TIMEOUT 0x06
57 #define SG_ERR_DRIVER_SENSE 0x08
60 #define MAX_UINT ((unsigned int)-1)
63 typedef struct SCSIRequest
{
64 BlockDriverAIOCB
*aiocb
;
65 struct SCSIRequest
*next
;
68 uint8_t cmd
[SCSI_CMD_BUF_SIZE
];
73 sg_io_hdr_t io_header
;
76 struct SCSIDeviceState
78 SCSIRequest
*requests
;
79 BlockDriverState
*bdrv
;
83 scsi_completionfn completion
;
86 uint8_t sensebuf
[SCSI_SENSE_BUF_SIZE
];
90 /* Global pool of SCSIRequest structures. */
91 static SCSIRequest
*free_requests
= NULL
;
93 static SCSIRequest
*scsi_new_request(SCSIDeviceState
*s
, uint32_t tag
)
99 free_requests
= r
->next
;
101 r
= qemu_malloc(sizeof(SCSIRequest
));
107 memset(r
->cmd
, 0, sizeof(r
->cmd
));
108 memset(&r
->io_header
, 0, sizeof(r
->io_header
));
115 r
->next
= s
->requests
;
120 static void scsi_remove_request(SCSIRequest
*r
)
123 SCSIDeviceState
*s
= r
->dev
;
125 if (s
->requests
== r
) {
126 s
->requests
= r
->next
;
129 while (last
&& last
->next
!= r
)
132 last
->next
= r
->next
;
134 BADF("Orphaned request\n");
137 r
->next
= free_requests
;
141 static SCSIRequest
*scsi_find_request(SCSIDeviceState
*s
, uint32_t tag
)
146 while (r
&& r
->tag
!= tag
)
152 /* Helper function for command completion. */
153 static void scsi_command_complete(void *opaque
, int ret
)
155 SCSIRequest
*r
= (SCSIRequest
*)opaque
;
156 SCSIDeviceState
*s
= r
->dev
;
160 s
->driver_status
= r
->io_header
.driver_status
;
161 if (s
->driver_status
& SG_ERR_DRIVER_SENSE
)
162 s
->senselen
= r
->io_header
.sb_len_wr
;
167 if (s
->driver_status
& SG_ERR_DRIVER_TIMEOUT
) {
169 BADF("Driver Timeout\n");
170 } else if (r
->io_header
.status
)
171 status
= r
->io_header
.status
;
172 else if (s
->driver_status
& SG_ERR_DRIVER_SENSE
)
173 status
= CHECK_CONDITION
<< 1;
177 DPRINTF("Command complete 0x%p tag=0x%x status=%d\n",
180 scsi_remove_request(r
);
181 s
->completion(s
->opaque
, SCSI_REASON_DONE
, tag
, status
);
184 /* Cancel a pending data transfer. */
185 static void scsi_cancel_io(SCSIDevice
*d
, uint32_t tag
)
187 DPRINTF("scsi_cancel_io 0x%x\n", tag
);
188 SCSIDeviceState
*s
= d
->state
;
190 DPRINTF("Cancel tag=0x%x\n", tag
);
191 r
= scsi_find_request(s
, tag
);
194 bdrv_aio_cancel(r
->aiocb
);
196 scsi_remove_request(r
);
200 static int execute_command(BlockDriverState
*bdrv
,
201 SCSIRequest
*r
, int direction
,
202 BlockDriverCompletionFunc
*complete
)
205 r
->io_header
.interface_id
= 'S';
206 r
->io_header
.dxfer_direction
= direction
;
207 r
->io_header
.dxferp
= r
->buf
;
208 r
->io_header
.dxfer_len
= r
->buflen
;
209 r
->io_header
.cmdp
= r
->cmd
;
210 r
->io_header
.cmd_len
= r
->cmdlen
;
211 r
->io_header
.mx_sb_len
= sizeof(r
->dev
->sensebuf
);
212 r
->io_header
.sbp
= r
->dev
->sensebuf
;
213 r
->io_header
.timeout
= MAX_UINT
;
214 r
->io_header
.usr_ptr
= r
;
215 r
->io_header
.flags
|= SG_FLAG_DIRECT_IO
;
217 if (bdrv_pwrite(bdrv
, -1, &r
->io_header
, sizeof(r
->io_header
)) == -1) {
218 BADF("execute_command: write failed ! (%d)\n", errno
);
221 if (complete
== NULL
) {
224 while ((ret
= bdrv_pread(bdrv
, -1, &r
->io_header
,
225 sizeof(r
->io_header
))) == -1 &&
228 BADF("execute_command: read failed !\n");
234 r
->aiocb
= bdrv_aio_read(bdrv
, 0, (uint8_t*)&r
->io_header
,
235 -(int64_t)sizeof(r
->io_header
), complete
, r
);
236 if (r
->aiocb
== NULL
) {
237 BADF("execute_command: read failed !\n");
244 static void scsi_read_complete(void * opaque
, int ret
)
246 SCSIRequest
*r
= (SCSIRequest
*)opaque
;
247 SCSIDeviceState
*s
= r
->dev
;
251 DPRINTF("IO error\n");
252 scsi_command_complete(r
, ret
);
255 len
= r
->io_header
.dxfer_len
- r
->io_header
.resid
;
256 DPRINTF("Data ready tag=0x%x len=%d\n", r
->tag
, len
);
259 s
->completion(s
->opaque
, SCSI_REASON_DATA
, r
->tag
, len
);
261 scsi_command_complete(r
, 0);
264 /* Read more data from scsi device into buffer. */
265 static void scsi_read_data(SCSIDevice
*d
, uint32_t tag
)
267 SCSIDeviceState
*s
= d
->state
;
271 DPRINTF("scsi_read_data 0x%x\n", tag
);
272 r
= scsi_find_request(s
, tag
);
274 BADF("Bad read tag 0x%x\n", tag
);
275 /* ??? This is the wrong error. */
276 scsi_command_complete(r
, -EINVAL
);
281 scsi_command_complete(r
, 0);
285 if (r
->cmd
[0] == REQUEST_SENSE
&& s
->driver_status
& SG_ERR_DRIVER_SENSE
)
287 s
->senselen
= MIN(r
->len
, s
->senselen
);
288 memcpy(r
->buf
, s
->sensebuf
, s
->senselen
);
289 r
->io_header
.driver_status
= 0;
290 r
->io_header
.status
= 0;
291 r
->io_header
.dxfer_len
= s
->senselen
;
293 DPRINTF("Data ready tag=0x%x len=%d\n", r
->tag
, s
->senselen
);
294 DPRINTF("Sense: %d %d %d %d %d %d %d %d\n",
295 r
->buf
[0], r
->buf
[1], r
->buf
[2], r
->buf
[3],
296 r
->buf
[4], r
->buf
[5], r
->buf
[6], r
->buf
[7]);
297 s
->completion(s
->opaque
, SCSI_REASON_DATA
, r
->tag
, s
->senselen
);
301 ret
= execute_command(s
->bdrv
, r
, SG_DXFER_FROM_DEV
, scsi_read_complete
);
303 scsi_command_complete(r
, -EINVAL
);
308 static void scsi_write_complete(void * opaque
, int ret
)
310 SCSIRequest
*r
= (SCSIRequest
*)opaque
;
312 DPRINTF("scsi_write_complete() ret = %d\n", ret
);
314 DPRINTF("IO error\n");
315 scsi_command_complete(r
, ret
);
319 if (r
->cmd
[0] == MODE_SELECT
&& r
->cmd
[4] == 12 &&
320 r
->dev
->type
== TYPE_TAPE
) {
321 r
->dev
->blocksize
= (r
->buf
[9] << 16) | (r
->buf
[10] << 8) | r
->buf
[11];
322 DPRINTF("block size %d\n", r
->dev
->blocksize
);
325 scsi_command_complete(r
, ret
);
328 /* Write data to a scsi device. Returns nonzero on failure.
329 The transfer may complete asynchronously. */
330 static int scsi_write_data(SCSIDevice
*d
, uint32_t tag
)
332 SCSIDeviceState
*s
= d
->state
;
336 DPRINTF("scsi_write_data 0x%x\n", tag
);
337 r
= scsi_find_request(s
, tag
);
339 BADF("Bad write tag 0x%x\n", tag
);
340 /* ??? This is the wrong error. */
341 scsi_command_complete(r
, -EINVAL
);
347 s
->completion(s
->opaque
, SCSI_REASON_DATA
, r
->tag
, r
->len
);
351 ret
= execute_command(s
->bdrv
, r
, SG_DXFER_TO_DEV
, scsi_write_complete
);
353 scsi_command_complete(r
, -EINVAL
);
360 /* Return a pointer to the data buffer. */
361 static uint8_t *scsi_get_buf(SCSIDevice
*d
, uint32_t tag
)
363 SCSIDeviceState
*s
= d
->state
;
365 r
= scsi_find_request(s
, tag
);
367 BADF("Bad buffer tag 0x%x\n", tag
);
373 static int scsi_length(uint8_t *cmd
, int blocksize
, int *cmdlen
, uint32_t *len
)
375 switch (cmd
[0] >> 5) {
379 /* length 0 means 256 blocks */
385 *len
= cmd
[8] | (cmd
[7] << 8);
389 *len
= cmd
[13] | (cmd
[12] << 8) | (cmd
[11] << 16) | (cmd
[10] << 24);
393 *len
= cmd
[9] | (cmd
[8] << 8) | (cmd
[7] << 16) | (cmd
[6] << 24);
401 case TEST_UNIT_READY
:
405 case WRITE_FILEMARKS
:
408 case ALLOW_MEDIUM_REMOVAL
:
411 case SYNCHRONIZE_CACHE
:
412 case LOCK_UNLOCK_CACHE
:
429 case READ_BLOCK_LIMITS
:
435 case SEND_VOLUME_TAG
:
442 cmd
[1] &= ~0x08; /* disable FUA */
446 case WRITE_VERIFY_12
:
450 cmd
[1] &= ~0x08; /* disable FUA */
453 case RECOVER_BUFFERED_DATA
:
458 *len
= cmd
[4] | (cmd
[3] << 8);
464 static int scsi_stream_length(uint8_t *cmd
, int blocksize
, int *cmdlen
, uint32_t *len
)
467 /* stream commands */
470 case RECOVER_BUFFERED_DATA
:
473 *len
= cmd
[4] | (cmd
[3] << 8) | (cmd
[2] << 16);
474 if (cmd
[1] & 0x01) /* fixed */
481 cmd
[1] = 0x01; /* force IMMED, otherwise qemu waits end of command */
483 /* generic commands */
485 return scsi_length(cmd
, blocksize
, cmdlen
, len
);
490 static int is_write(int command
)
496 case CHANGE_DEFINITION
:
500 case SEND_DIAGNOSTIC
:
503 case REASSIGN_BLOCKS
:
515 case SEARCH_EQUAL_12
:
518 case WRITE_VERIFY_12
:
521 case SEND_VOLUME_TAG
:
528 /* Execute a scsi command. Returns the length of the data expected by the
529 command. This will be Positive for data transfers from the device
530 (eg. disk reads), negative for transfers to the device (eg. disk writes),
531 and zero if the command does not transfer any data. */
533 static int32_t scsi_send_command(SCSIDevice
*d
, uint32_t tag
,
534 uint8_t *cmd
, int lun
)
536 SCSIDeviceState
*s
= d
->state
;
542 if (s
->type
== TYPE_TAPE
) {
543 if (scsi_stream_length(cmd
, s
->blocksize
, &cmdlen
, &len
) == -1) {
544 BADF("Unsupported command length, command %x\n", cmd
[0]);
548 if (scsi_length(cmd
, s
->blocksize
, &cmdlen
, &len
) == -1) {
549 BADF("Unsupported command length, command %x\n", cmd
[0]);
554 DPRINTF("Command: lun=%d tag=0x%x data=0x%02x len %d\n", lun
, tag
,
557 if (cmd
[0] != REQUEST_SENSE
&&
558 (lun
!= s
->lun
|| (cmd
[1] >> 5) != s
->lun
)) {
559 DPRINTF("Unimplemented LUN %d\n", lun
? lun
: cmd
[1] >> 5);
561 s
->sensebuf
[0] = 0x70;
562 s
->sensebuf
[1] = 0x00;
563 s
->sensebuf
[2] = ILLEGAL_REQUEST
;
564 s
->sensebuf
[3] = 0x00;
565 s
->sensebuf
[4] = 0x00;
566 s
->sensebuf
[5] = 0x00;
567 s
->sensebuf
[6] = 0x00;
569 s
->driver_status
= SG_ERR_DRIVER_SENSE
;
570 s
->completion(s
->opaque
, SCSI_REASON_DONE
, tag
, CHECK_CONDITION
<< 1);
574 r
= scsi_find_request(s
, tag
);
576 BADF("Tag 0x%x already in use %p\n", tag
, r
);
577 scsi_cancel_io(d
, tag
);
579 r
= scsi_new_request(s
, tag
);
581 memcpy(r
->cmd
, cmd
, cmdlen
);
589 ret
= execute_command(s
->bdrv
, r
, SG_DXFER_NONE
, scsi_command_complete
);
591 scsi_command_complete(r
, -EINVAL
);
597 if (r
->buflen
!= len
) {
600 r
->buf
= qemu_malloc(len
);
604 memset(r
->buf
, 0, r
->buflen
);
606 if (is_write(cmd
[0])) {
614 static int get_blocksize(BlockDriverState
*bdrv
)
619 sg_io_hdr_t io_header
;
622 memset(cmd
, 0, sizeof(cmd
));
623 memset(buf
, 0, sizeof(buf
));
624 cmd
[0] = READ_CAPACITY
;
626 memset(&io_header
, 0, sizeof(io_header
));
627 io_header
.interface_id
= 'S';
628 io_header
.dxfer_direction
= SG_DXFER_FROM_DEV
;
629 io_header
.dxfer_len
= sizeof(buf
);
630 io_header
.dxferp
= buf
;
631 io_header
.cmdp
= cmd
;
632 io_header
.cmd_len
= sizeof(cmd
);
633 io_header
.mx_sb_len
= sizeof(sensebuf
);
634 io_header
.sbp
= sensebuf
;
635 io_header
.timeout
= 6000; /* XXX */
637 ret
= bdrv_pwrite(bdrv
, -1, &io_header
, sizeof(io_header
));
641 while ((ret
= bdrv_pread(bdrv
, -1, &io_header
, sizeof(io_header
))) == -1 &&
647 return (buf
[4] << 24) | (buf
[5] << 16) | (buf
[6] << 8) | buf
[7];
650 static int get_stream_blocksize(BlockDriverState
*bdrv
)
655 sg_io_hdr_t io_header
;
658 memset(cmd
, 0, sizeof(cmd
));
659 memset(buf
, 0, sizeof(buf
));
661 cmd
[4] = sizeof(buf
);
663 memset(&io_header
, 0, sizeof(io_header
));
664 io_header
.interface_id
= 'S';
665 io_header
.dxfer_direction
= SG_DXFER_FROM_DEV
;
666 io_header
.dxfer_len
= sizeof(buf
);
667 io_header
.dxferp
= buf
;
668 io_header
.cmdp
= cmd
;
669 io_header
.cmd_len
= sizeof(cmd
);
670 io_header
.mx_sb_len
= sizeof(sensebuf
);
671 io_header
.sbp
= sensebuf
;
672 io_header
.timeout
= 6000; /* XXX */
674 ret
= bdrv_pwrite(bdrv
, -1, &io_header
, sizeof(io_header
));
678 while ((ret
= bdrv_pread(bdrv
, -1, &io_header
, sizeof(io_header
))) == -1 &&
684 return (buf
[9] << 16) | (buf
[10] << 8) | buf
[11];
687 static void scsi_destroy(SCSIDevice
*d
)
691 r
= d
->state
->requests
;
709 SCSIDevice
*scsi_generic_init(BlockDriverState
*bdrv
, int tcq
,
710 scsi_completionfn completion
, void *opaque
)
715 struct sg_scsi_id scsiid
;
717 /* check we are really using a /dev/sg* file */
719 if (!bdrv_is_sg(bdrv
))
722 /* check we are using a driver managing SG_IO (version 3 and after */
724 if (bdrv_ioctl(bdrv
, SG_GET_VERSION_NUM
, &sg_version
) < 0 ||
728 /* get LUN of the /dev/sg? */
730 if (bdrv_ioctl(bdrv
, SG_GET_SCSI_ID
, &scsiid
))
733 /* define device state */
735 s
= (SCSIDeviceState
*)qemu_mallocz(sizeof(SCSIDeviceState
));
738 s
->completion
= completion
;
741 DPRINTF("LUN %d\n", s
->lun
);
742 s
->type
= scsiid
.scsi_type
;
743 DPRINTF("device type %d\n", s
->type
);
744 if (s
->type
== TYPE_TAPE
) {
745 s
->blocksize
= get_stream_blocksize(s
->bdrv
);
746 if (s
->blocksize
== -1)
749 s
->blocksize
= get_blocksize(s
->bdrv
);
750 /* removable media returns 0 if not present */
751 if (s
->blocksize
<= 0) {
752 if (s
->type
== TYPE_ROM
|| s
->type
== TYPE_WORM
)
758 DPRINTF("block size %d\n", s
->blocksize
);
759 s
->driver_status
= 0;
760 memset(s
->sensebuf
, 0, sizeof(s
->sensebuf
));
762 /* define function to manage device */
764 d
= (SCSIDevice
*)qemu_mallocz(sizeof(SCSIDevice
));
766 d
->destroy
= scsi_destroy
;
767 d
->send_command
= scsi_send_command
;
768 d
->read_data
= scsi_read_data
;
769 d
->write_data
= scsi_write_data
;
770 d
->cancel_io
= scsi_cancel_io
;
771 d
->get_buf
= scsi_get_buf
;
775 #endif /* __linux__ */