]> git.proxmox.com Git - qemu.git/blob - hw/scsi/scsi-generic.c
19bd36cd541b400b549b2ae701dae2abb29e5f7e
[qemu.git] / hw / scsi / 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-report.h"
16 #include "hw/scsi/scsi.h"
17 #include "sysemu/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 "block/scsi.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 #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
49
50 #ifndef MAX_UINT
51 #define MAX_UINT ((unsigned int)-1)
52 #endif
53
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;
61
62 static void scsi_generic_save_request(QEMUFile *f, SCSIRequest *req)
63 {
64 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
65
66 qemu_put_sbe32s(f, &r->buflen);
67 if (r->buflen && r->req.cmd.mode == SCSI_XFER_TO_DEV) {
68 assert(!r->req.sg);
69 qemu_put_buffer(f, r->buf, r->req.cmd.xfer);
70 }
71 }
72
73 static void scsi_generic_load_request(QEMUFile *f, SCSIRequest *req)
74 {
75 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
76
77 qemu_get_sbe32s(f, &r->buflen);
78 if (r->buflen && r->req.cmd.mode == SCSI_XFER_TO_DEV) {
79 assert(!r->req.sg);
80 qemu_get_buffer(f, r->buf, r->req.cmd.xfer);
81 }
82 }
83
84 static void scsi_free_request(SCSIRequest *req)
85 {
86 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
87
88 g_free(r->buf);
89 }
90
91 /* Helper function for command completion. */
92 static void scsi_command_complete(void *opaque, int ret)
93 {
94 int status;
95 SCSIGenericReq *r = (SCSIGenericReq *)opaque;
96
97 r->req.aiocb = NULL;
98 if (r->io_header.driver_status & SG_ERR_DRIVER_SENSE) {
99 r->req.sense_len = r->io_header.sb_len_wr;
100 }
101
102 if (ret != 0) {
103 switch (ret) {
104 case -EDOM:
105 status = TASK_SET_FULL;
106 break;
107 case -ENOMEM:
108 status = CHECK_CONDITION;
109 scsi_req_build_sense(&r->req, SENSE_CODE(TARGET_FAILURE));
110 break;
111 default:
112 status = CHECK_CONDITION;
113 scsi_req_build_sense(&r->req, SENSE_CODE(IO_ERROR));
114 break;
115 }
116 } else {
117 if (r->io_header.host_status == SG_ERR_DID_NO_CONNECT ||
118 r->io_header.host_status == SG_ERR_DID_BUS_BUSY ||
119 r->io_header.host_status == SG_ERR_DID_TIME_OUT ||
120 (r->io_header.driver_status & SG_ERR_DRIVER_TIMEOUT)) {
121 status = BUSY;
122 BADF("Driver Timeout\n");
123 } else if (r->io_header.host_status) {
124 status = CHECK_CONDITION;
125 scsi_req_build_sense(&r->req, SENSE_CODE(I_T_NEXUS_LOSS));
126 } else if (r->io_header.status) {
127 status = r->io_header.status;
128 } else if (r->io_header.driver_status & SG_ERR_DRIVER_SENSE) {
129 status = CHECK_CONDITION;
130 } else {
131 status = GOOD;
132 }
133 }
134 DPRINTF("Command complete 0x%p tag=0x%x status=%d\n",
135 r, r->req.tag, status);
136
137 scsi_req_complete(&r->req, status);
138 if (!r->req.io_canceled) {
139 scsi_req_unref(&r->req);
140 }
141 }
142
143 /* Cancel a pending data transfer. */
144 static void scsi_cancel_io(SCSIRequest *req)
145 {
146 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
147
148 DPRINTF("Cancel tag=0x%x\n", req->tag);
149 if (r->req.aiocb) {
150 bdrv_aio_cancel(r->req.aiocb);
151
152 /* This reference was left in by scsi_*_data. We take ownership of
153 * it independent of whether bdrv_aio_cancel completes the request
154 * or not. */
155 scsi_req_unref(&r->req);
156 }
157 r->req.aiocb = NULL;
158 }
159
160 static int execute_command(BlockDriverState *bdrv,
161 SCSIGenericReq *r, int direction,
162 BlockDriverCompletionFunc *complete)
163 {
164 r->io_header.interface_id = 'S';
165 r->io_header.dxfer_direction = direction;
166 r->io_header.dxferp = r->buf;
167 r->io_header.dxfer_len = r->buflen;
168 r->io_header.cmdp = r->req.cmd.buf;
169 r->io_header.cmd_len = r->req.cmd.len;
170 r->io_header.mx_sb_len = sizeof(r->req.sense);
171 r->io_header.sbp = r->req.sense;
172 r->io_header.timeout = MAX_UINT;
173 r->io_header.usr_ptr = r;
174 r->io_header.flags |= SG_FLAG_DIRECT_IO;
175
176 r->req.aiocb = bdrv_aio_ioctl(bdrv, SG_IO, &r->io_header, complete, r);
177
178 return 0;
179 }
180
181 static void scsi_read_complete(void * opaque, int ret)
182 {
183 SCSIGenericReq *r = (SCSIGenericReq *)opaque;
184 SCSIDevice *s = r->req.dev;
185 int len;
186
187 r->req.aiocb = NULL;
188 if (ret) {
189 DPRINTF("IO error ret %d\n", ret);
190 scsi_command_complete(r, ret);
191 return;
192 }
193 len = r->io_header.dxfer_len - r->io_header.resid;
194 DPRINTF("Data ready tag=0x%x len=%d\n", r->req.tag, len);
195
196 r->len = -1;
197 if (len == 0) {
198 scsi_command_complete(r, 0);
199 } else {
200 /* Snoop READ CAPACITY output to set the blocksize. */
201 if (r->req.cmd.buf[0] == READ_CAPACITY_10 &&
202 (ldl_be_p(&r->buf[0]) != 0xffffffffU || s->max_lba == 0)) {
203 s->blocksize = ldl_be_p(&r->buf[4]);
204 s->max_lba = ldl_be_p(&r->buf[0]) & 0xffffffffULL;
205 } else if (r->req.cmd.buf[0] == SERVICE_ACTION_IN_16 &&
206 (r->req.cmd.buf[1] & 31) == SAI_READ_CAPACITY_16) {
207 s->blocksize = ldl_be_p(&r->buf[8]);
208 s->max_lba = ldq_be_p(&r->buf[0]);
209 }
210 bdrv_set_buffer_alignment(s->conf.bs, s->blocksize);
211
212 scsi_req_data(&r->req, len);
213 if (!r->req.io_canceled) {
214 scsi_req_unref(&r->req);
215 }
216 }
217 }
218
219 /* Read more data from scsi device into buffer. */
220 static void scsi_read_data(SCSIRequest *req)
221 {
222 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
223 SCSIDevice *s = r->req.dev;
224 int ret;
225
226 DPRINTF("scsi_read_data 0x%x\n", req->tag);
227
228 /* The request is used as the AIO opaque value, so add a ref. */
229 scsi_req_ref(&r->req);
230 if (r->len == -1) {
231 scsi_command_complete(r, 0);
232 return;
233 }
234
235 ret = execute_command(s->conf.bs, r, SG_DXFER_FROM_DEV, scsi_read_complete);
236 if (ret < 0) {
237 scsi_command_complete(r, ret);
238 }
239 }
240
241 static void scsi_write_complete(void * opaque, int ret)
242 {
243 SCSIGenericReq *r = (SCSIGenericReq *)opaque;
244 SCSIDevice *s = r->req.dev;
245
246 DPRINTF("scsi_write_complete() ret = %d\n", ret);
247 r->req.aiocb = NULL;
248 if (ret) {
249 DPRINTF("IO error\n");
250 scsi_command_complete(r, ret);
251 return;
252 }
253
254 if (r->req.cmd.buf[0] == MODE_SELECT && r->req.cmd.buf[4] == 12 &&
255 s->type == TYPE_TAPE) {
256 s->blocksize = (r->buf[9] << 16) | (r->buf[10] << 8) | r->buf[11];
257 DPRINTF("block size %d\n", s->blocksize);
258 }
259
260 scsi_command_complete(r, ret);
261 }
262
263 /* Write data to a scsi device. Returns nonzero on failure.
264 The transfer may complete asynchronously. */
265 static void scsi_write_data(SCSIRequest *req)
266 {
267 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
268 SCSIDevice *s = r->req.dev;
269 int ret;
270
271 DPRINTF("scsi_write_data 0x%x\n", req->tag);
272 if (r->len == 0) {
273 r->len = r->buflen;
274 scsi_req_data(&r->req, r->len);
275 return;
276 }
277
278 /* The request is used as the AIO opaque value, so add a ref. */
279 scsi_req_ref(&r->req);
280 ret = execute_command(s->conf.bs, r, SG_DXFER_TO_DEV, scsi_write_complete);
281 if (ret < 0) {
282 scsi_command_complete(r, ret);
283 }
284 }
285
286 /* Return a pointer to the data buffer. */
287 static uint8_t *scsi_get_buf(SCSIRequest *req)
288 {
289 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
290
291 return r->buf;
292 }
293
294 /* Execute a scsi command. Returns the length of the data expected by the
295 command. This will be Positive for data transfers from the device
296 (eg. disk reads), negative for transfers to the device (eg. disk writes),
297 and zero if the command does not transfer any data. */
298
299 static int32_t scsi_send_command(SCSIRequest *req, uint8_t *cmd)
300 {
301 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
302 SCSIDevice *s = r->req.dev;
303 int ret;
304
305 DPRINTF("Command: lun=%d tag=0x%x len %zd data=0x%02x", lun, tag,
306 r->req.cmd.xfer, cmd[0]);
307
308 #ifdef DEBUG_SCSI
309 {
310 int i;
311 for (i = 1; i < r->req.cmd.len; i++) {
312 printf(" 0x%02x", cmd[i]);
313 }
314 printf("\n");
315 }
316 #endif
317
318 if (r->req.cmd.xfer == 0) {
319 if (r->buf != NULL)
320 g_free(r->buf);
321 r->buflen = 0;
322 r->buf = NULL;
323 /* The request is used as the AIO opaque value, so add a ref. */
324 scsi_req_ref(&r->req);
325 ret = execute_command(s->conf.bs, r, SG_DXFER_NONE, scsi_command_complete);
326 if (ret < 0) {
327 scsi_command_complete(r, ret);
328 return 0;
329 }
330 return 0;
331 }
332
333 if (r->buflen != r->req.cmd.xfer) {
334 if (r->buf != NULL)
335 g_free(r->buf);
336 r->buf = g_malloc(r->req.cmd.xfer);
337 r->buflen = r->req.cmd.xfer;
338 }
339
340 memset(r->buf, 0, r->buflen);
341 r->len = r->req.cmd.xfer;
342 if (r->req.cmd.mode == SCSI_XFER_TO_DEV) {
343 r->len = 0;
344 return -r->req.cmd.xfer;
345 } else {
346 return r->req.cmd.xfer;
347 }
348 }
349
350 static int get_stream_blocksize(BlockDriverState *bdrv)
351 {
352 uint8_t cmd[6];
353 uint8_t buf[12];
354 uint8_t sensebuf[8];
355 sg_io_hdr_t io_header;
356 int ret;
357
358 memset(cmd, 0, sizeof(cmd));
359 memset(buf, 0, sizeof(buf));
360 cmd[0] = MODE_SENSE;
361 cmd[4] = sizeof(buf);
362
363 memset(&io_header, 0, sizeof(io_header));
364 io_header.interface_id = 'S';
365 io_header.dxfer_direction = SG_DXFER_FROM_DEV;
366 io_header.dxfer_len = sizeof(buf);
367 io_header.dxferp = buf;
368 io_header.cmdp = cmd;
369 io_header.cmd_len = sizeof(cmd);
370 io_header.mx_sb_len = sizeof(sensebuf);
371 io_header.sbp = sensebuf;
372 io_header.timeout = 6000; /* XXX */
373
374 ret = bdrv_ioctl(bdrv, SG_IO, &io_header);
375 if (ret < 0 || io_header.driver_status || io_header.host_status) {
376 return -1;
377 }
378 return (buf[9] << 16) | (buf[10] << 8) | buf[11];
379 }
380
381 static void scsi_generic_reset(DeviceState *dev)
382 {
383 SCSIDevice *s = SCSI_DEVICE(dev);
384
385 scsi_device_purge_requests(s, SENSE_CODE(RESET));
386 }
387
388 static void scsi_destroy(SCSIDevice *s)
389 {
390 scsi_device_purge_requests(s, SENSE_CODE(NO_SENSE));
391 blockdev_mark_auto_del(s->conf.bs);
392 }
393
394 static int scsi_generic_initfn(SCSIDevice *s)
395 {
396 int sg_version;
397 struct sg_scsi_id scsiid;
398
399 if (!s->conf.bs) {
400 error_report("drive property not set");
401 return -1;
402 }
403
404 if (bdrv_get_on_error(s->conf.bs, 0) != BLOCKDEV_ON_ERROR_ENOSPC) {
405 error_report("Device doesn't support drive option werror");
406 return -1;
407 }
408 if (bdrv_get_on_error(s->conf.bs, 1) != BLOCKDEV_ON_ERROR_REPORT) {
409 error_report("Device doesn't support drive option rerror");
410 return -1;
411 }
412
413 /* check we are using a driver managing SG_IO (version 3 and after */
414 if (bdrv_ioctl(s->conf.bs, SG_GET_VERSION_NUM, &sg_version) < 0) {
415 error_report("scsi generic interface not supported");
416 return -1;
417 }
418 if (sg_version < 30000) {
419 error_report("scsi generic interface too old");
420 return -1;
421 }
422
423 /* get LUN of the /dev/sg? */
424 if (bdrv_ioctl(s->conf.bs, SG_GET_SCSI_ID, &scsiid)) {
425 error_report("SG_GET_SCSI_ID ioctl failed");
426 return -1;
427 }
428
429 /* define device state */
430 s->type = scsiid.scsi_type;
431 DPRINTF("device type %d\n", s->type);
432 if (s->type == TYPE_DISK || s->type == TYPE_ROM) {
433 add_boot_device_path(s->conf.bootindex, &s->qdev, NULL);
434 }
435
436 switch (s->type) {
437 case TYPE_TAPE:
438 s->blocksize = get_stream_blocksize(s->conf.bs);
439 if (s->blocksize == -1) {
440 s->blocksize = 0;
441 }
442 break;
443
444 /* Make a guess for block devices, we'll fix it when the guest sends.
445 * READ CAPACITY. If they don't, they likely would assume these sizes
446 * anyway. (TODO: they could also send MODE SENSE).
447 */
448 case TYPE_ROM:
449 case TYPE_WORM:
450 s->blocksize = 2048;
451 break;
452 default:
453 s->blocksize = 512;
454 break;
455 }
456
457 DPRINTF("block size %d\n", s->blocksize);
458 return 0;
459 }
460
461 const SCSIReqOps scsi_generic_req_ops = {
462 .size = sizeof(SCSIGenericReq),
463 .free_req = scsi_free_request,
464 .send_command = scsi_send_command,
465 .read_data = scsi_read_data,
466 .write_data = scsi_write_data,
467 .cancel_io = scsi_cancel_io,
468 .get_buf = scsi_get_buf,
469 .load_request = scsi_generic_load_request,
470 .save_request = scsi_generic_save_request,
471 };
472
473 static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun,
474 uint8_t *buf, void *hba_private)
475 {
476 SCSIRequest *req;
477
478 req = scsi_req_alloc(&scsi_generic_req_ops, d, tag, lun, hba_private);
479 return req;
480 }
481
482 static Property scsi_generic_properties[] = {
483 DEFINE_PROP_DRIVE("drive", SCSIDevice, conf.bs),
484 DEFINE_PROP_INT32("bootindex", SCSIDevice, conf.bootindex, -1),
485 DEFINE_PROP_END_OF_LIST(),
486 };
487
488 static void scsi_generic_class_initfn(ObjectClass *klass, void *data)
489 {
490 DeviceClass *dc = DEVICE_CLASS(klass);
491 SCSIDeviceClass *sc = SCSI_DEVICE_CLASS(klass);
492
493 sc->init = scsi_generic_initfn;
494 sc->destroy = scsi_destroy;
495 sc->alloc_req = scsi_new_request;
496 dc->fw_name = "disk";
497 dc->desc = "pass through generic scsi device (/dev/sg*)";
498 dc->reset = scsi_generic_reset;
499 dc->props = scsi_generic_properties;
500 dc->vmsd = &vmstate_scsi_device;
501 }
502
503 static const TypeInfo scsi_generic_info = {
504 .name = "scsi-generic",
505 .parent = TYPE_SCSI_DEVICE,
506 .instance_size = sizeof(SCSIDevice),
507 .class_init = scsi_generic_class_initfn,
508 };
509
510 static void scsi_generic_register_types(void)
511 {
512 type_register_static(&scsi_generic_info);
513 }
514
515 type_init(scsi_generic_register_types)
516
517 #endif /* __linux__ */