]> git.proxmox.com Git - mirror_qemu.git/blob - hw/scsi-generic.c
Merge remote-tracking branch 'qemu-kvm-tmp/memory/batch' into staging
[mirror_qemu.git] / 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 licensed under the LGPL.
11 *
12 */
13
14 #include "qemu-common.h"
15 #include "qemu-error.h"
16 #include "scsi.h"
17 #include "blockdev.h"
18
19 #ifdef __linux__
20
21 //#define DEBUG_SCSI
22
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
29
30 #define BADF(fmt, ...) \
31 do { fprintf(stderr, "scsi-generic: " fmt , ## __VA_ARGS__); } while (0)
32
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"
39
40 #define SCSI_SENSE_BUF_SIZE 96
41
42 #define SG_ERR_DRIVER_TIMEOUT 0x06
43 #define SG_ERR_DRIVER_SENSE 0x08
44
45 #ifndef MAX_UINT
46 #define MAX_UINT ((unsigned int)-1)
47 #endif
48
49 typedef struct SCSIGenericState SCSIGenericState;
50
51 typedef struct SCSIGenericReq {
52 SCSIRequest req;
53 uint8_t *buf;
54 int buflen;
55 int len;
56 sg_io_hdr_t io_header;
57 } SCSIGenericReq;
58
59 struct SCSIGenericState
60 {
61 SCSIDevice qdev;
62 BlockDriverState *bs;
63 };
64
65 static void scsi_free_request(SCSIRequest *req)
66 {
67 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
68
69 g_free(r->buf);
70 }
71
72 /* Helper function for command completion. */
73 static void scsi_command_complete(void *opaque, int ret)
74 {
75 int status;
76 SCSIGenericReq *r = (SCSIGenericReq *)opaque;
77
78 r->req.aiocb = NULL;
79 if (r->io_header.driver_status & SG_ERR_DRIVER_SENSE)
80 r->req.sense_len = r->io_header.sb_len_wr;
81
82 if (ret != 0) {
83 switch (ret) {
84 case -EDOM:
85 status = TASK_SET_FULL;
86 break;
87 case -ENOMEM:
88 status = CHECK_CONDITION;
89 scsi_req_build_sense(&r->req, SENSE_CODE(TARGET_FAILURE));
90 break;
91 default:
92 status = CHECK_CONDITION;
93 scsi_req_build_sense(&r->req, SENSE_CODE(IO_ERROR));
94 break;
95 }
96 } else {
97 if (r->io_header.driver_status & SG_ERR_DRIVER_TIMEOUT) {
98 status = BUSY;
99 BADF("Driver Timeout\n");
100 } else if (r->io_header.status) {
101 status = r->io_header.status;
102 } else if (r->io_header.driver_status & SG_ERR_DRIVER_SENSE) {
103 status = CHECK_CONDITION;
104 } else {
105 status = GOOD;
106 }
107 }
108 DPRINTF("Command complete 0x%p tag=0x%x status=%d\n",
109 r, r->req.tag, status);
110
111 scsi_req_complete(&r->req, status);
112 }
113
114 /* Cancel a pending data transfer. */
115 static void scsi_cancel_io(SCSIRequest *req)
116 {
117 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
118
119 DPRINTF("Cancel tag=0x%x\n", req->tag);
120 if (r->req.aiocb) {
121 bdrv_aio_cancel(r->req.aiocb);
122 }
123 r->req.aiocb = NULL;
124 }
125
126 static int execute_command(BlockDriverState *bdrv,
127 SCSIGenericReq *r, int direction,
128 BlockDriverCompletionFunc *complete)
129 {
130 r->io_header.interface_id = 'S';
131 r->io_header.dxfer_direction = direction;
132 r->io_header.dxferp = r->buf;
133 r->io_header.dxfer_len = r->buflen;
134 r->io_header.cmdp = r->req.cmd.buf;
135 r->io_header.cmd_len = r->req.cmd.len;
136 r->io_header.mx_sb_len = sizeof(r->req.sense);
137 r->io_header.sbp = r->req.sense;
138 r->io_header.timeout = MAX_UINT;
139 r->io_header.usr_ptr = r;
140 r->io_header.flags |= SG_FLAG_DIRECT_IO;
141
142 r->req.aiocb = bdrv_aio_ioctl(bdrv, SG_IO, &r->io_header, complete, r);
143 if (r->req.aiocb == NULL) {
144 BADF("execute_command: read failed !\n");
145 return -ENOMEM;
146 }
147
148 return 0;
149 }
150
151 static void scsi_read_complete(void * opaque, int ret)
152 {
153 SCSIGenericReq *r = (SCSIGenericReq *)opaque;
154 int len;
155
156 r->req.aiocb = NULL;
157 if (ret) {
158 DPRINTF("IO error ret %d\n", ret);
159 scsi_command_complete(r, ret);
160 return;
161 }
162 len = r->io_header.dxfer_len - r->io_header.resid;
163 DPRINTF("Data ready tag=0x%x len=%d\n", r->req.tag, len);
164
165 r->len = -1;
166 if (len == 0) {
167 scsi_command_complete(r, 0);
168 } else {
169 scsi_req_data(&r->req, len);
170 }
171 }
172
173 /* Read more data from scsi device into buffer. */
174 static void scsi_read_data(SCSIRequest *req)
175 {
176 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
177 SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, r->req.dev);
178 int ret;
179
180 DPRINTF("scsi_read_data 0x%x\n", req->tag);
181 if (r->len == -1) {
182 scsi_command_complete(r, 0);
183 return;
184 }
185
186 ret = execute_command(s->bs, r, SG_DXFER_FROM_DEV, scsi_read_complete);
187 if (ret < 0) {
188 scsi_command_complete(r, ret);
189 return;
190 }
191 }
192
193 static void scsi_write_complete(void * opaque, int ret)
194 {
195 SCSIGenericReq *r = (SCSIGenericReq *)opaque;
196 SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, r->req.dev);
197
198 DPRINTF("scsi_write_complete() ret = %d\n", ret);
199 r->req.aiocb = NULL;
200 if (ret) {
201 DPRINTF("IO error\n");
202 scsi_command_complete(r, ret);
203 return;
204 }
205
206 if (r->req.cmd.buf[0] == MODE_SELECT && r->req.cmd.buf[4] == 12 &&
207 s->qdev.type == TYPE_TAPE) {
208 s->qdev.blocksize = (r->buf[9] << 16) | (r->buf[10] << 8) | r->buf[11];
209 DPRINTF("block size %d\n", s->qdev.blocksize);
210 }
211
212 scsi_command_complete(r, ret);
213 }
214
215 /* Write data to a scsi device. Returns nonzero on failure.
216 The transfer may complete asynchronously. */
217 static void scsi_write_data(SCSIRequest *req)
218 {
219 SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, req->dev);
220 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
221 int ret;
222
223 DPRINTF("scsi_write_data 0x%x\n", req->tag);
224 if (r->len == 0) {
225 r->len = r->buflen;
226 scsi_req_data(&r->req, r->len);
227 return;
228 }
229
230 ret = execute_command(s->bs, r, SG_DXFER_TO_DEV, scsi_write_complete);
231 if (ret < 0) {
232 scsi_command_complete(r, ret);
233 }
234 }
235
236 /* Return a pointer to the data buffer. */
237 static uint8_t *scsi_get_buf(SCSIRequest *req)
238 {
239 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
240
241 return r->buf;
242 }
243
244 static void scsi_req_fixup(SCSIRequest *req)
245 {
246 switch(req->cmd.buf[0]) {
247 case REWIND:
248 case START_STOP:
249 if (req->dev->type == TYPE_TAPE) {
250 /* force IMMED, otherwise qemu waits end of command */
251 req->cmd.buf[1] = 0x01;
252 }
253 break;
254 }
255 }
256
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. */
261
262 static int32_t scsi_send_command(SCSIRequest *req, uint8_t *cmd)
263 {
264 SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, req->dev);
265 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
266 int ret;
267
268 scsi_req_fixup(&r->req);
269
270 DPRINTF("Command: lun=%d tag=0x%x len %zd data=0x%02x", lun, tag,
271 r->req.cmd.xfer, cmd[0]);
272
273 #ifdef DEBUG_SCSI
274 {
275 int i;
276 for (i = 1; i < r->req.cmd.len; i++) {
277 printf(" 0x%02x", cmd[i]);
278 }
279 printf("\n");
280 }
281 #endif
282
283 if (r->req.cmd.xfer == 0) {
284 if (r->buf != NULL)
285 g_free(r->buf);
286 r->buflen = 0;
287 r->buf = NULL;
288 ret = execute_command(s->bs, r, SG_DXFER_NONE, scsi_command_complete);
289 if (ret < 0) {
290 scsi_command_complete(r, ret);
291 return 0;
292 }
293 return 0;
294 }
295
296 if (r->buflen != r->req.cmd.xfer) {
297 if (r->buf != NULL)
298 g_free(r->buf);
299 r->buf = g_malloc(r->req.cmd.xfer);
300 r->buflen = r->req.cmd.xfer;
301 }
302
303 memset(r->buf, 0, r->buflen);
304 r->len = r->req.cmd.xfer;
305 if (r->req.cmd.mode == SCSI_XFER_TO_DEV) {
306 r->len = 0;
307 return -r->req.cmd.xfer;
308 } else {
309 return r->req.cmd.xfer;
310 }
311 }
312
313 static int get_blocksize(BlockDriverState *bdrv)
314 {
315 uint8_t cmd[10];
316 uint8_t buf[8];
317 uint8_t sensebuf[8];
318 sg_io_hdr_t io_header;
319 int ret;
320
321 memset(cmd, 0, sizeof(cmd));
322 memset(buf, 0, sizeof(buf));
323 cmd[0] = READ_CAPACITY_10;
324
325 memset(&io_header, 0, sizeof(io_header));
326 io_header.interface_id = 'S';
327 io_header.dxfer_direction = SG_DXFER_FROM_DEV;
328 io_header.dxfer_len = sizeof(buf);
329 io_header.dxferp = buf;
330 io_header.cmdp = cmd;
331 io_header.cmd_len = sizeof(cmd);
332 io_header.mx_sb_len = sizeof(sensebuf);
333 io_header.sbp = sensebuf;
334 io_header.timeout = 6000; /* XXX */
335
336 ret = bdrv_ioctl(bdrv, SG_IO, &io_header);
337 if (ret < 0)
338 return -1;
339
340 return (buf[4] << 24) | (buf[5] << 16) | (buf[6] << 8) | buf[7];
341 }
342
343 static int get_stream_blocksize(BlockDriverState *bdrv)
344 {
345 uint8_t cmd[6];
346 uint8_t buf[12];
347 uint8_t sensebuf[8];
348 sg_io_hdr_t io_header;
349 int ret;
350
351 memset(cmd, 0, sizeof(cmd));
352 memset(buf, 0, sizeof(buf));
353 cmd[0] = MODE_SENSE;
354 cmd[4] = sizeof(buf);
355
356 memset(&io_header, 0, sizeof(io_header));
357 io_header.interface_id = 'S';
358 io_header.dxfer_direction = SG_DXFER_FROM_DEV;
359 io_header.dxfer_len = sizeof(buf);
360 io_header.dxferp = buf;
361 io_header.cmdp = cmd;
362 io_header.cmd_len = sizeof(cmd);
363 io_header.mx_sb_len = sizeof(sensebuf);
364 io_header.sbp = sensebuf;
365 io_header.timeout = 6000; /* XXX */
366
367 ret = bdrv_ioctl(bdrv, SG_IO, &io_header);
368 if (ret < 0)
369 return -1;
370
371 return (buf[9] << 16) | (buf[10] << 8) | buf[11];
372 }
373
374 static void scsi_generic_reset(DeviceState *dev)
375 {
376 SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev.qdev, dev);
377
378 scsi_device_purge_requests(&s->qdev, SENSE_CODE(RESET));
379 }
380
381 static void scsi_destroy(SCSIDevice *d)
382 {
383 SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, d);
384
385 scsi_device_purge_requests(&s->qdev, SENSE_CODE(NO_SENSE));
386 blockdev_mark_auto_del(s->qdev.conf.bs);
387 }
388
389 static int scsi_generic_initfn(SCSIDevice *dev)
390 {
391 SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, dev);
392 int sg_version;
393 struct sg_scsi_id scsiid;
394
395 if (!s->qdev.conf.bs) {
396 error_report("scsi-generic: drive property not set");
397 return -1;
398 }
399 s->bs = s->qdev.conf.bs;
400
401 /* check we are really using a /dev/sg* file */
402 if (!bdrv_is_sg(s->bs)) {
403 error_report("scsi-generic: not /dev/sg*");
404 return -1;
405 }
406
407 if (bdrv_get_on_error(s->bs, 0) != BLOCK_ERR_STOP_ENOSPC) {
408 error_report("Device doesn't support drive option werror");
409 return -1;
410 }
411 if (bdrv_get_on_error(s->bs, 1) != BLOCK_ERR_REPORT) {
412 error_report("Device doesn't support drive option rerror");
413 return -1;
414 }
415
416 /* check we are using a driver managing SG_IO (version 3 and after */
417 if (bdrv_ioctl(s->bs, SG_GET_VERSION_NUM, &sg_version) < 0 ||
418 sg_version < 30000) {
419 error_report("scsi-generic: scsi generic interface too old");
420 return -1;
421 }
422
423 /* get LUN of the /dev/sg? */
424 if (bdrv_ioctl(s->bs, SG_GET_SCSI_ID, &scsiid)) {
425 error_report("scsi-generic: SG_GET_SCSI_ID ioctl failed");
426 return -1;
427 }
428
429 /* define device state */
430 s->qdev.type = scsiid.scsi_type;
431 DPRINTF("device type %d\n", s->qdev.type);
432 if (s->qdev.type == TYPE_TAPE) {
433 s->qdev.blocksize = get_stream_blocksize(s->bs);
434 if (s->qdev.blocksize == -1)
435 s->qdev.blocksize = 0;
436 } else {
437 s->qdev.blocksize = get_blocksize(s->bs);
438 /* removable media returns 0 if not present */
439 if (s->qdev.blocksize <= 0) {
440 if (s->qdev.type == TYPE_ROM || s->qdev.type == TYPE_WORM)
441 s->qdev.blocksize = 2048;
442 else
443 s->qdev.blocksize = 512;
444 }
445 }
446 DPRINTF("block size %d\n", s->qdev.blocksize);
447 return 0;
448 }
449
450 static SCSIReqOps scsi_generic_req_ops = {
451 .size = sizeof(SCSIGenericReq),
452 .free_req = scsi_free_request,
453 .send_command = scsi_send_command,
454 .read_data = scsi_read_data,
455 .write_data = scsi_write_data,
456 .cancel_io = scsi_cancel_io,
457 .get_buf = scsi_get_buf,
458 };
459
460 static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun,
461 void *hba_private)
462 {
463 SCSIRequest *req;
464
465 req = scsi_req_alloc(&scsi_generic_req_ops, d, tag, lun, hba_private);
466 return req;
467 }
468
469 static SCSIDeviceInfo scsi_generic_info = {
470 .qdev.name = "scsi-generic",
471 .qdev.desc = "pass through generic scsi device (/dev/sg*)",
472 .qdev.size = sizeof(SCSIGenericState),
473 .qdev.reset = scsi_generic_reset,
474 .init = scsi_generic_initfn,
475 .destroy = scsi_destroy,
476 .alloc_req = scsi_new_request,
477 .qdev.props = (Property[]) {
478 DEFINE_BLOCK_PROPERTIES(SCSIGenericState, qdev.conf),
479 DEFINE_PROP_END_OF_LIST(),
480 },
481 };
482
483 static void scsi_generic_register_devices(void)
484 {
485 scsi_qdev_register(&scsi_generic_info);
486 }
487 device_init(scsi_generic_register_devices)
488
489 #endif /* __linux__ */