scsi-generic: snoop READ CAPACITY commands to get block size
[qemu.git] / hw / scsi-generic.c
blob4d7ad828f1bcf15c81c355127c64664f26db42a8
1 /*
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 licensed under the LGPL.
14 #include "qemu-common.h"
15 #include "qemu-error.h"
16 #include "scsi.h"
17 #include "blockdev.h"
19 #ifdef __linux__
21 //#define DEBUG_SCSI
23 #ifdef DEBUG_SCSI
24 #define DPRINTF(fmt, ...) \
25 do { printf("scsi-generic: " fmt , ## __VA_ARGS__); } while (0)
26 #else
27 #define DPRINTF(fmt, ...) do {} while(0)
28 #endif
30 #define BADF(fmt, ...) \
31 do { fprintf(stderr, "scsi-generic: " fmt , ## __VA_ARGS__); } while (0)
33 #include <stdio.h>
34 #include <sys/types.h>
35 #include <sys/stat.h>
36 #include <unistd.h>
37 #include <scsi/sg.h>
38 #include "scsi-defs.h"
40 #define SCSI_SENSE_BUF_SIZE 96
42 #define SG_ERR_DRIVER_TIMEOUT 0x06
43 #define SG_ERR_DRIVER_SENSE 0x08
45 #define SG_ERR_DID_OK 0x00
46 #define SG_ERR_DID_NO_CONNECT 0x01
47 #define SG_ERR_DID_BUS_BUSY 0x02
48 #define SG_ERR_DID_TIME_OUT 0x03
50 #ifndef MAX_UINT
51 #define MAX_UINT ((unsigned int)-1)
52 #endif
54 typedef struct SCSIGenericReq {
55 SCSIRequest req;
56 uint8_t *buf;
57 int buflen;
58 int len;
59 sg_io_hdr_t io_header;
60 } SCSIGenericReq;
62 static void scsi_free_request(SCSIRequest *req)
64 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
66 g_free(r->buf);
69 /* Helper function for command completion. */
70 static void scsi_command_complete(void *opaque, int ret)
72 int status;
73 SCSIGenericReq *r = (SCSIGenericReq *)opaque;
75 r->req.aiocb = NULL;
76 if (r->io_header.driver_status & SG_ERR_DRIVER_SENSE) {
77 r->req.sense_len = r->io_header.sb_len_wr;
80 if (ret != 0) {
81 switch (ret) {
82 case -EDOM:
83 status = TASK_SET_FULL;
84 break;
85 case -ENOMEM:
86 status = CHECK_CONDITION;
87 scsi_req_build_sense(&r->req, SENSE_CODE(TARGET_FAILURE));
88 break;
89 default:
90 status = CHECK_CONDITION;
91 scsi_req_build_sense(&r->req, SENSE_CODE(IO_ERROR));
92 break;
94 } else {
95 if (r->io_header.host_status == SG_ERR_DID_NO_CONNECT ||
96 r->io_header.host_status == SG_ERR_DID_BUS_BUSY ||
97 r->io_header.host_status == SG_ERR_DID_TIME_OUT ||
98 (r->io_header.driver_status & SG_ERR_DRIVER_TIMEOUT)) {
99 status = BUSY;
100 BADF("Driver Timeout\n");
101 } else if (r->io_header.host_status) {
102 status = CHECK_CONDITION;
103 scsi_req_build_sense(&r->req, SENSE_CODE(I_T_NEXUS_LOSS));
104 } else if (r->io_header.status) {
105 status = r->io_header.status;
106 } else if (r->io_header.driver_status & SG_ERR_DRIVER_SENSE) {
107 status = CHECK_CONDITION;
108 } else {
109 status = GOOD;
112 DPRINTF("Command complete 0x%p tag=0x%x status=%d\n",
113 r, r->req.tag, status);
115 scsi_req_complete(&r->req, status);
118 /* Cancel a pending data transfer. */
119 static void scsi_cancel_io(SCSIRequest *req)
121 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
123 DPRINTF("Cancel tag=0x%x\n", req->tag);
124 if (r->req.aiocb) {
125 bdrv_aio_cancel(r->req.aiocb);
127 r->req.aiocb = NULL;
130 static int execute_command(BlockDriverState *bdrv,
131 SCSIGenericReq *r, int direction,
132 BlockDriverCompletionFunc *complete)
134 r->io_header.interface_id = 'S';
135 r->io_header.dxfer_direction = direction;
136 r->io_header.dxferp = r->buf;
137 r->io_header.dxfer_len = r->buflen;
138 r->io_header.cmdp = r->req.cmd.buf;
139 r->io_header.cmd_len = r->req.cmd.len;
140 r->io_header.mx_sb_len = sizeof(r->req.sense);
141 r->io_header.sbp = r->req.sense;
142 r->io_header.timeout = MAX_UINT;
143 r->io_header.usr_ptr = r;
144 r->io_header.flags |= SG_FLAG_DIRECT_IO;
146 r->req.aiocb = bdrv_aio_ioctl(bdrv, SG_IO, &r->io_header, complete, r);
147 if (r->req.aiocb == NULL) {
148 BADF("execute_command: read failed !\n");
149 return -ENOMEM;
152 return 0;
155 static void scsi_read_complete(void * opaque, int ret)
157 SCSIGenericReq *r = (SCSIGenericReq *)opaque;
158 SCSIDevice *s = r->req.dev;
159 int len;
161 r->req.aiocb = NULL;
162 if (ret) {
163 DPRINTF("IO error ret %d\n", ret);
164 scsi_command_complete(r, ret);
165 return;
167 len = r->io_header.dxfer_len - r->io_header.resid;
168 DPRINTF("Data ready tag=0x%x len=%d\n", r->req.tag, len);
170 r->len = -1;
171 if (len == 0) {
172 scsi_command_complete(r, 0);
173 } else {
174 /* Snoop READ CAPACITY output to set the blocksize. */
175 if (r->req.cmd.buf[0] == READ_CAPACITY_10) {
176 s->blocksize = ldl_be_p(&r->buf[4]);
177 } else if (r->req.cmd.buf[0] == SERVICE_ACTION_IN_16 &&
178 (r->req.cmd.buf[1] & 31) == SAI_READ_CAPACITY_16) {
179 s->blocksize = ldl_be_p(&r->buf[8]);
181 bdrv_set_buffer_alignment(s->conf.bs, s->blocksize);
183 scsi_req_data(&r->req, len);
187 /* Read more data from scsi device into buffer. */
188 static void scsi_read_data(SCSIRequest *req)
190 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
191 SCSIDevice *s = r->req.dev;
192 int ret;
194 DPRINTF("scsi_read_data 0x%x\n", req->tag);
195 if (r->len == -1) {
196 scsi_command_complete(r, 0);
197 return;
200 ret = execute_command(s->conf.bs, r, SG_DXFER_FROM_DEV, scsi_read_complete);
201 if (ret < 0) {
202 scsi_command_complete(r, ret);
206 static void scsi_write_complete(void * opaque, int ret)
208 SCSIGenericReq *r = (SCSIGenericReq *)opaque;
209 SCSIDevice *s = r->req.dev;
211 DPRINTF("scsi_write_complete() ret = %d\n", ret);
212 r->req.aiocb = NULL;
213 if (ret) {
214 DPRINTF("IO error\n");
215 scsi_command_complete(r, ret);
216 return;
219 if (r->req.cmd.buf[0] == MODE_SELECT && r->req.cmd.buf[4] == 12 &&
220 s->type == TYPE_TAPE) {
221 s->blocksize = (r->buf[9] << 16) | (r->buf[10] << 8) | r->buf[11];
222 DPRINTF("block size %d\n", s->blocksize);
225 scsi_command_complete(r, ret);
228 /* Write data to a scsi device. Returns nonzero on failure.
229 The transfer may complete asynchronously. */
230 static void scsi_write_data(SCSIRequest *req)
232 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
233 SCSIDevice *s = r->req.dev;
234 int ret;
236 DPRINTF("scsi_write_data 0x%x\n", req->tag);
237 if (r->len == 0) {
238 r->len = r->buflen;
239 scsi_req_data(&r->req, r->len);
240 return;
243 ret = execute_command(s->conf.bs, r, SG_DXFER_TO_DEV, scsi_write_complete);
244 if (ret < 0) {
245 scsi_command_complete(r, ret);
249 /* Return a pointer to the data buffer. */
250 static uint8_t *scsi_get_buf(SCSIRequest *req)
252 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
254 return r->buf;
257 /* Execute a scsi command. Returns the length of the data expected by the
258 command. This will be Positive for data transfers from the device
259 (eg. disk reads), negative for transfers to the device (eg. disk writes),
260 and zero if the command does not transfer any data. */
262 static int32_t scsi_send_command(SCSIRequest *req, uint8_t *cmd)
264 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
265 SCSIDevice *s = r->req.dev;
266 int ret;
268 DPRINTF("Command: lun=%d tag=0x%x len %zd data=0x%02x", lun, tag,
269 r->req.cmd.xfer, cmd[0]);
271 #ifdef DEBUG_SCSI
273 int i;
274 for (i = 1; i < r->req.cmd.len; i++) {
275 printf(" 0x%02x", cmd[i]);
277 printf("\n");
279 #endif
281 if (r->req.cmd.xfer == 0) {
282 if (r->buf != NULL)
283 g_free(r->buf);
284 r->buflen = 0;
285 r->buf = NULL;
286 ret = execute_command(s->conf.bs, r, SG_DXFER_NONE, scsi_command_complete);
287 if (ret < 0) {
288 scsi_command_complete(r, ret);
289 return 0;
291 return 0;
294 if (r->buflen != r->req.cmd.xfer) {
295 if (r->buf != NULL)
296 g_free(r->buf);
297 r->buf = g_malloc(r->req.cmd.xfer);
298 r->buflen = r->req.cmd.xfer;
301 memset(r->buf, 0, r->buflen);
302 r->len = r->req.cmd.xfer;
303 if (r->req.cmd.mode == SCSI_XFER_TO_DEV) {
304 r->len = 0;
305 return -r->req.cmd.xfer;
306 } else {
307 return r->req.cmd.xfer;
311 static int get_stream_blocksize(BlockDriverState *bdrv)
313 uint8_t cmd[6];
314 uint8_t buf[12];
315 uint8_t sensebuf[8];
316 sg_io_hdr_t io_header;
317 int ret;
319 memset(cmd, 0, sizeof(cmd));
320 memset(buf, 0, sizeof(buf));
321 cmd[0] = MODE_SENSE;
322 cmd[4] = sizeof(buf);
324 memset(&io_header, 0, sizeof(io_header));
325 io_header.interface_id = 'S';
326 io_header.dxfer_direction = SG_DXFER_FROM_DEV;
327 io_header.dxfer_len = sizeof(buf);
328 io_header.dxferp = buf;
329 io_header.cmdp = cmd;
330 io_header.cmd_len = sizeof(cmd);
331 io_header.mx_sb_len = sizeof(sensebuf);
332 io_header.sbp = sensebuf;
333 io_header.timeout = 6000; /* XXX */
335 ret = bdrv_ioctl(bdrv, SG_IO, &io_header);
336 if (ret < 0 || io_header.driver_status || io_header.host_status) {
337 return -1;
339 return (buf[9] << 16) | (buf[10] << 8) | buf[11];
342 static void scsi_generic_reset(DeviceState *dev)
344 SCSIDevice *s = DO_UPCAST(SCSIDevice, qdev, dev);
346 scsi_device_purge_requests(s, SENSE_CODE(RESET));
349 static void scsi_destroy(SCSIDevice *s)
351 scsi_device_purge_requests(s, SENSE_CODE(NO_SENSE));
352 blockdev_mark_auto_del(s->conf.bs);
355 static int scsi_generic_initfn(SCSIDevice *s)
357 int sg_version;
358 struct sg_scsi_id scsiid;
360 if (!s->conf.bs) {
361 error_report("scsi-generic: drive property not set");
362 return -1;
365 /* check we are really using a /dev/sg* file */
366 if (!bdrv_is_sg(s->conf.bs)) {
367 error_report("scsi-generic: not /dev/sg*");
368 return -1;
371 if (bdrv_get_on_error(s->conf.bs, 0) != BLOCK_ERR_STOP_ENOSPC) {
372 error_report("Device doesn't support drive option werror");
373 return -1;
375 if (bdrv_get_on_error(s->conf.bs, 1) != BLOCK_ERR_REPORT) {
376 error_report("Device doesn't support drive option rerror");
377 return -1;
380 /* check we are using a driver managing SG_IO (version 3 and after */
381 if (bdrv_ioctl(s->conf.bs, SG_GET_VERSION_NUM, &sg_version) < 0 ||
382 sg_version < 30000) {
383 error_report("scsi-generic: scsi generic interface too old");
384 return -1;
387 /* get LUN of the /dev/sg? */
388 if (bdrv_ioctl(s->conf.bs, SG_GET_SCSI_ID, &scsiid)) {
389 error_report("scsi-generic: SG_GET_SCSI_ID ioctl failed");
390 return -1;
393 /* define device state */
394 s->type = scsiid.scsi_type;
395 DPRINTF("device type %d\n", s->type);
396 switch (s->type) {
397 case TYPE_TAPE:
398 s->blocksize = get_stream_blocksize(s->conf.bs);
399 if (s->blocksize == -1) {
400 s->blocksize = 0;
402 break;
404 /* Make a guess for block devices, we'll fix it when the guest sends.
405 * READ CAPACITY. If they don't, they likely would assume these sizes
406 * anyway. (TODO: they could also send MODE SENSE).
408 case TYPE_ROM:
409 case TYPE_WORM:
410 s->blocksize = 2048;
411 break;
412 default:
413 s->blocksize = 512;
414 break;
417 DPRINTF("block size %d\n", s->blocksize);
418 return 0;
421 static SCSIReqOps scsi_generic_req_ops = {
422 .size = sizeof(SCSIGenericReq),
423 .free_req = scsi_free_request,
424 .send_command = scsi_send_command,
425 .read_data = scsi_read_data,
426 .write_data = scsi_write_data,
427 .cancel_io = scsi_cancel_io,
428 .get_buf = scsi_get_buf,
431 static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun,
432 void *hba_private)
434 SCSIRequest *req;
436 req = scsi_req_alloc(&scsi_generic_req_ops, d, tag, lun, hba_private);
437 return req;
440 static SCSIDeviceInfo scsi_generic_info = {
441 .qdev.name = "scsi-generic",
442 .qdev.desc = "pass through generic scsi device (/dev/sg*)",
443 .qdev.size = sizeof(SCSIDevice),
444 .qdev.reset = scsi_generic_reset,
445 .init = scsi_generic_initfn,
446 .destroy = scsi_destroy,
447 .alloc_req = scsi_new_request,
448 .qdev.props = (Property[]) {
449 DEFINE_BLOCK_PROPERTIES(SCSIDevice, conf),
450 DEFINE_PROP_END_OF_LIST(),
454 static void scsi_generic_register_devices(void)
456 scsi_qdev_register(&scsi_generic_info);
458 device_init(scsi_generic_register_devices)
460 #endif /* __linux__ */