]> git.ipfire.org Git - thirdparty/qemu.git/blob - hw/scsi/scsi-generic.c
include/qemu/osdep.h: Don't include qapi/error.h
[thirdparty/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/osdep.h"
15 #include "qapi/error.h"
16 #include "qemu-common.h"
17 #include "qemu/error-report.h"
18 #include "hw/scsi/scsi.h"
19 #include "sysemu/block-backend.h"
20 #include "sysemu/blockdev.h"
21
22 #ifdef __linux__
23
24 //#define DEBUG_SCSI
25
26 #ifdef DEBUG_SCSI
27 #define DPRINTF(fmt, ...) \
28 do { printf("scsi-generic: " fmt , ## __VA_ARGS__); } while (0)
29 #else
30 #define DPRINTF(fmt, ...) do {} while(0)
31 #endif
32
33 #define BADF(fmt, ...) \
34 do { fprintf(stderr, "scsi-generic: " fmt , ## __VA_ARGS__); } while (0)
35
36 #include <scsi/sg.h>
37 #include "block/scsi.h"
38
39 #define SG_ERR_DRIVER_TIMEOUT 0x06
40 #define SG_ERR_DRIVER_SENSE 0x08
41
42 #define SG_ERR_DID_OK 0x00
43 #define SG_ERR_DID_NO_CONNECT 0x01
44 #define SG_ERR_DID_BUS_BUSY 0x02
45 #define SG_ERR_DID_TIME_OUT 0x03
46
47 #ifndef MAX_UINT
48 #define MAX_UINT ((unsigned int)-1)
49 #endif
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 static void scsi_generic_save_request(QEMUFile *f, SCSIRequest *req)
60 {
61 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
62
63 qemu_put_sbe32s(f, &r->buflen);
64 if (r->buflen && r->req.cmd.mode == SCSI_XFER_TO_DEV) {
65 assert(!r->req.sg);
66 qemu_put_buffer(f, r->buf, r->req.cmd.xfer);
67 }
68 }
69
70 static void scsi_generic_load_request(QEMUFile *f, SCSIRequest *req)
71 {
72 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
73
74 qemu_get_sbe32s(f, &r->buflen);
75 if (r->buflen && r->req.cmd.mode == SCSI_XFER_TO_DEV) {
76 assert(!r->req.sg);
77 qemu_get_buffer(f, r->buf, r->req.cmd.xfer);
78 }
79 }
80
81 static void scsi_free_request(SCSIRequest *req)
82 {
83 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
84
85 g_free(r->buf);
86 }
87
88 /* Helper function for command completion. */
89 static void scsi_command_complete_noio(SCSIGenericReq *r, int ret)
90 {
91 int status;
92
93 assert(r->req.aiocb == NULL);
94
95 if (r->req.io_canceled) {
96 scsi_req_cancel_complete(&r->req);
97 goto done;
98 }
99 if (r->io_header.driver_status & SG_ERR_DRIVER_SENSE) {
100 r->req.sense_len = r->io_header.sb_len_wr;
101 }
102
103 if (ret != 0) {
104 switch (ret) {
105 case -EDOM:
106 status = TASK_SET_FULL;
107 break;
108 case -ENOMEM:
109 status = CHECK_CONDITION;
110 scsi_req_build_sense(&r->req, SENSE_CODE(TARGET_FAILURE));
111 break;
112 default:
113 status = CHECK_CONDITION;
114 scsi_req_build_sense(&r->req, SENSE_CODE(IO_ERROR));
115 break;
116 }
117 } else {
118 if (r->io_header.host_status == SG_ERR_DID_NO_CONNECT ||
119 r->io_header.host_status == SG_ERR_DID_BUS_BUSY ||
120 r->io_header.host_status == SG_ERR_DID_TIME_OUT ||
121 (r->io_header.driver_status & SG_ERR_DRIVER_TIMEOUT)) {
122 status = BUSY;
123 BADF("Driver Timeout\n");
124 } else if (r->io_header.host_status) {
125 status = CHECK_CONDITION;
126 scsi_req_build_sense(&r->req, SENSE_CODE(I_T_NEXUS_LOSS));
127 } else if (r->io_header.status) {
128 status = r->io_header.status;
129 } else if (r->io_header.driver_status & SG_ERR_DRIVER_SENSE) {
130 status = CHECK_CONDITION;
131 } else {
132 status = GOOD;
133 }
134 }
135 DPRINTF("Command complete 0x%p tag=0x%x status=%d\n",
136 r, r->req.tag, status);
137
138 scsi_req_complete(&r->req, status);
139 done:
140 scsi_req_unref(&r->req);
141 }
142
143 static void scsi_command_complete(void *opaque, int ret)
144 {
145 SCSIGenericReq *r = (SCSIGenericReq *)opaque;
146
147 assert(r->req.aiocb != NULL);
148 r->req.aiocb = NULL;
149 scsi_command_complete_noio(r, ret);
150 }
151
152 static int execute_command(BlockBackend *blk,
153 SCSIGenericReq *r, int direction,
154 BlockCompletionFunc *complete)
155 {
156 r->io_header.interface_id = 'S';
157 r->io_header.dxfer_direction = direction;
158 r->io_header.dxferp = r->buf;
159 r->io_header.dxfer_len = r->buflen;
160 r->io_header.cmdp = r->req.cmd.buf;
161 r->io_header.cmd_len = r->req.cmd.len;
162 r->io_header.mx_sb_len = sizeof(r->req.sense);
163 r->io_header.sbp = r->req.sense;
164 r->io_header.timeout = MAX_UINT;
165 r->io_header.usr_ptr = r;
166 r->io_header.flags |= SG_FLAG_DIRECT_IO;
167
168 r->req.aiocb = blk_aio_ioctl(blk, SG_IO, &r->io_header, complete, r);
169 if (r->req.aiocb == NULL) {
170 return -EIO;
171 }
172
173 return 0;
174 }
175
176 static void scsi_read_complete(void * opaque, int ret)
177 {
178 SCSIGenericReq *r = (SCSIGenericReq *)opaque;
179 SCSIDevice *s = r->req.dev;
180 int len;
181
182 assert(r->req.aiocb != NULL);
183 r->req.aiocb = NULL;
184
185 if (ret || r->req.io_canceled) {
186 scsi_command_complete_noio(r, ret);
187 return;
188 }
189
190 len = r->io_header.dxfer_len - r->io_header.resid;
191 DPRINTF("Data ready tag=0x%x len=%d\n", r->req.tag, len);
192
193 r->len = -1;
194 if (len == 0) {
195 scsi_command_complete_noio(r, 0);
196 return;
197 }
198
199 /* Snoop READ CAPACITY output to set the blocksize. */
200 if (r->req.cmd.buf[0] == READ_CAPACITY_10 &&
201 (ldl_be_p(&r->buf[0]) != 0xffffffffU || s->max_lba == 0)) {
202 s->blocksize = ldl_be_p(&r->buf[4]);
203 s->max_lba = ldl_be_p(&r->buf[0]) & 0xffffffffULL;
204 } else if (r->req.cmd.buf[0] == SERVICE_ACTION_IN_16 &&
205 (r->req.cmd.buf[1] & 31) == SAI_READ_CAPACITY_16) {
206 s->blocksize = ldl_be_p(&r->buf[8]);
207 s->max_lba = ldq_be_p(&r->buf[0]);
208 }
209 blk_set_guest_block_size(s->conf.blk, s->blocksize);
210
211 /* Patch MODE SENSE device specific parameters if the BDS is opened
212 * readonly.
213 */
214 if ((s->type == TYPE_DISK || s->type == TYPE_TAPE) &&
215 blk_is_read_only(s->conf.blk) &&
216 (r->req.cmd.buf[0] == MODE_SENSE ||
217 r->req.cmd.buf[0] == MODE_SENSE_10) &&
218 (r->req.cmd.buf[1] & 0x8) == 0) {
219 if (r->req.cmd.buf[0] == MODE_SENSE) {
220 r->buf[2] |= 0x80;
221 } else {
222 r->buf[3] |= 0x80;
223 }
224 }
225 scsi_req_data(&r->req, len);
226 scsi_req_unref(&r->req);
227 }
228
229 /* Read more data from scsi device into buffer. */
230 static void scsi_read_data(SCSIRequest *req)
231 {
232 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
233 SCSIDevice *s = r->req.dev;
234 int ret;
235
236 DPRINTF("scsi_read_data 0x%x\n", req->tag);
237
238 /* The request is used as the AIO opaque value, so add a ref. */
239 scsi_req_ref(&r->req);
240 if (r->len == -1) {
241 scsi_command_complete_noio(r, 0);
242 return;
243 }
244
245 ret = execute_command(s->conf.blk, r, SG_DXFER_FROM_DEV,
246 scsi_read_complete);
247 if (ret < 0) {
248 scsi_command_complete_noio(r, ret);
249 }
250 }
251
252 static void scsi_write_complete(void * opaque, int ret)
253 {
254 SCSIGenericReq *r = (SCSIGenericReq *)opaque;
255 SCSIDevice *s = r->req.dev;
256
257 DPRINTF("scsi_write_complete() ret = %d\n", ret);
258
259 assert(r->req.aiocb != NULL);
260 r->req.aiocb = NULL;
261
262 if (ret || r->req.io_canceled) {
263 scsi_command_complete_noio(r, ret);
264 return;
265 }
266
267 if (r->req.cmd.buf[0] == MODE_SELECT && r->req.cmd.buf[4] == 12 &&
268 s->type == TYPE_TAPE) {
269 s->blocksize = (r->buf[9] << 16) | (r->buf[10] << 8) | r->buf[11];
270 DPRINTF("block size %d\n", s->blocksize);
271 }
272
273 scsi_command_complete_noio(r, ret);
274 }
275
276 /* Write data to a scsi device. Returns nonzero on failure.
277 The transfer may complete asynchronously. */
278 static void scsi_write_data(SCSIRequest *req)
279 {
280 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
281 SCSIDevice *s = r->req.dev;
282 int ret;
283
284 DPRINTF("scsi_write_data 0x%x\n", req->tag);
285 if (r->len == 0) {
286 r->len = r->buflen;
287 scsi_req_data(&r->req, r->len);
288 return;
289 }
290
291 /* The request is used as the AIO opaque value, so add a ref. */
292 scsi_req_ref(&r->req);
293 ret = execute_command(s->conf.blk, r, SG_DXFER_TO_DEV, scsi_write_complete);
294 if (ret < 0) {
295 scsi_command_complete_noio(r, ret);
296 }
297 }
298
299 /* Return a pointer to the data buffer. */
300 static uint8_t *scsi_get_buf(SCSIRequest *req)
301 {
302 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
303
304 return r->buf;
305 }
306
307 /* Execute a scsi command. Returns the length of the data expected by the
308 command. This will be Positive for data transfers from the device
309 (eg. disk reads), negative for transfers to the device (eg. disk writes),
310 and zero if the command does not transfer any data. */
311
312 static int32_t scsi_send_command(SCSIRequest *req, uint8_t *cmd)
313 {
314 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
315 SCSIDevice *s = r->req.dev;
316 int ret;
317
318 #ifdef DEBUG_SCSI
319 {
320 int i;
321 for (i = 1; i < r->req.cmd.len; i++) {
322 printf(" 0x%02x", cmd[i]);
323 }
324 printf("\n");
325 }
326 #endif
327
328 if (r->req.cmd.xfer == 0) {
329 g_free(r->buf);
330 r->buflen = 0;
331 r->buf = NULL;
332 /* The request is used as the AIO opaque value, so add a ref. */
333 scsi_req_ref(&r->req);
334 ret = execute_command(s->conf.blk, r, SG_DXFER_NONE,
335 scsi_command_complete);
336 if (ret < 0) {
337 scsi_command_complete_noio(r, ret);
338 return 0;
339 }
340 return 0;
341 }
342
343 if (r->buflen != r->req.cmd.xfer) {
344 g_free(r->buf);
345 r->buf = g_malloc(r->req.cmd.xfer);
346 r->buflen = r->req.cmd.xfer;
347 }
348
349 memset(r->buf, 0, r->buflen);
350 r->len = r->req.cmd.xfer;
351 if (r->req.cmd.mode == SCSI_XFER_TO_DEV) {
352 r->len = 0;
353 return -r->req.cmd.xfer;
354 } else {
355 return r->req.cmd.xfer;
356 }
357 }
358
359 static int read_naa_id(const uint8_t *p, uint64_t *p_wwn)
360 {
361 int i;
362
363 if ((p[1] & 0xF) == 3) {
364 /* NAA designator type */
365 if (p[3] != 8) {
366 return -EINVAL;
367 }
368 *p_wwn = ldq_be_p(p + 4);
369 return 0;
370 }
371
372 if ((p[1] & 0xF) == 8) {
373 /* SCSI name string designator type */
374 if (p[3] < 20 || memcmp(&p[4], "naa.", 4)) {
375 return -EINVAL;
376 }
377 if (p[3] > 20 && p[24] != ',') {
378 return -EINVAL;
379 }
380 *p_wwn = 0;
381 for (i = 8; i < 24; i++) {
382 char c = toupper(p[i]);
383 c -= (c >= '0' && c <= '9' ? '0' : 'A' - 10);
384 *p_wwn = (*p_wwn << 4) | c;
385 }
386 return 0;
387 }
388
389 return -EINVAL;
390 }
391
392 void scsi_generic_read_device_identification(SCSIDevice *s)
393 {
394 uint8_t cmd[6];
395 uint8_t buf[250];
396 uint8_t sensebuf[8];
397 sg_io_hdr_t io_header;
398 int ret;
399 int i, len;
400
401 memset(cmd, 0, sizeof(cmd));
402 memset(buf, 0, sizeof(buf));
403 cmd[0] = INQUIRY;
404 cmd[1] = 1;
405 cmd[2] = 0x83;
406 cmd[4] = sizeof(buf);
407
408 memset(&io_header, 0, sizeof(io_header));
409 io_header.interface_id = 'S';
410 io_header.dxfer_direction = SG_DXFER_FROM_DEV;
411 io_header.dxfer_len = sizeof(buf);
412 io_header.dxferp = buf;
413 io_header.cmdp = cmd;
414 io_header.cmd_len = sizeof(cmd);
415 io_header.mx_sb_len = sizeof(sensebuf);
416 io_header.sbp = sensebuf;
417 io_header.timeout = 6000; /* XXX */
418
419 ret = blk_ioctl(s->conf.blk, SG_IO, &io_header);
420 if (ret < 0 || io_header.driver_status || io_header.host_status) {
421 return;
422 }
423
424 len = MIN((buf[2] << 8) | buf[3], sizeof(buf) - 4);
425 for (i = 0; i + 3 <= len; ) {
426 const uint8_t *p = &buf[i + 4];
427 uint64_t wwn;
428
429 if (i + (p[3] + 4) > len) {
430 break;
431 }
432
433 if ((p[1] & 0x10) == 0) {
434 /* Associated with the logical unit */
435 if (read_naa_id(p, &wwn) == 0) {
436 s->wwn = wwn;
437 }
438 } else if ((p[1] & 0x10) == 0x10) {
439 /* Associated with the target port */
440 if (read_naa_id(p, &wwn) == 0) {
441 s->port_wwn = wwn;
442 }
443 }
444
445 i += p[3] + 4;
446 }
447 }
448
449 static int get_stream_blocksize(BlockBackend *blk)
450 {
451 uint8_t cmd[6];
452 uint8_t buf[12];
453 uint8_t sensebuf[8];
454 sg_io_hdr_t io_header;
455 int ret;
456
457 memset(cmd, 0, sizeof(cmd));
458 memset(buf, 0, sizeof(buf));
459 cmd[0] = MODE_SENSE;
460 cmd[4] = sizeof(buf);
461
462 memset(&io_header, 0, sizeof(io_header));
463 io_header.interface_id = 'S';
464 io_header.dxfer_direction = SG_DXFER_FROM_DEV;
465 io_header.dxfer_len = sizeof(buf);
466 io_header.dxferp = buf;
467 io_header.cmdp = cmd;
468 io_header.cmd_len = sizeof(cmd);
469 io_header.mx_sb_len = sizeof(sensebuf);
470 io_header.sbp = sensebuf;
471 io_header.timeout = 6000; /* XXX */
472
473 ret = blk_ioctl(blk, SG_IO, &io_header);
474 if (ret < 0 || io_header.driver_status || io_header.host_status) {
475 return -1;
476 }
477 return (buf[9] << 16) | (buf[10] << 8) | buf[11];
478 }
479
480 static void scsi_generic_reset(DeviceState *dev)
481 {
482 SCSIDevice *s = SCSI_DEVICE(dev);
483
484 scsi_device_purge_requests(s, SENSE_CODE(RESET));
485 }
486
487 static void scsi_generic_realize(SCSIDevice *s, Error **errp)
488 {
489 int rc;
490 int sg_version;
491 struct sg_scsi_id scsiid;
492
493 if (!s->conf.blk) {
494 error_setg(errp, "drive property not set");
495 return;
496 }
497
498 if (blk_get_on_error(s->conf.blk, 0) != BLOCKDEV_ON_ERROR_ENOSPC) {
499 error_setg(errp, "Device doesn't support drive option werror");
500 return;
501 }
502 if (blk_get_on_error(s->conf.blk, 1) != BLOCKDEV_ON_ERROR_REPORT) {
503 error_setg(errp, "Device doesn't support drive option rerror");
504 return;
505 }
506
507 /* check we are using a driver managing SG_IO (version 3 and after */
508 rc = blk_ioctl(s->conf.blk, SG_GET_VERSION_NUM, &sg_version);
509 if (rc < 0) {
510 error_setg(errp, "cannot get SG_IO version number: %s. "
511 "Is this a SCSI device?",
512 strerror(-rc));
513 return;
514 }
515 if (sg_version < 30000) {
516 error_setg(errp, "scsi generic interface too old");
517 return;
518 }
519
520 /* get LUN of the /dev/sg? */
521 if (blk_ioctl(s->conf.blk, SG_GET_SCSI_ID, &scsiid)) {
522 error_setg(errp, "SG_GET_SCSI_ID ioctl failed");
523 return;
524 }
525
526 /* define device state */
527 s->type = scsiid.scsi_type;
528 DPRINTF("device type %d\n", s->type);
529
530 switch (s->type) {
531 case TYPE_TAPE:
532 s->blocksize = get_stream_blocksize(s->conf.blk);
533 if (s->blocksize == -1) {
534 s->blocksize = 0;
535 }
536 break;
537
538 /* Make a guess for block devices, we'll fix it when the guest sends.
539 * READ CAPACITY. If they don't, they likely would assume these sizes
540 * anyway. (TODO: they could also send MODE SENSE).
541 */
542 case TYPE_ROM:
543 case TYPE_WORM:
544 s->blocksize = 2048;
545 break;
546 default:
547 s->blocksize = 512;
548 break;
549 }
550
551 DPRINTF("block size %d\n", s->blocksize);
552
553 scsi_generic_read_device_identification(s);
554 }
555
556 const SCSIReqOps scsi_generic_req_ops = {
557 .size = sizeof(SCSIGenericReq),
558 .free_req = scsi_free_request,
559 .send_command = scsi_send_command,
560 .read_data = scsi_read_data,
561 .write_data = scsi_write_data,
562 .get_buf = scsi_get_buf,
563 .load_request = scsi_generic_load_request,
564 .save_request = scsi_generic_save_request,
565 };
566
567 static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun,
568 uint8_t *buf, void *hba_private)
569 {
570 SCSIRequest *req;
571
572 req = scsi_req_alloc(&scsi_generic_req_ops, d, tag, lun, hba_private);
573 return req;
574 }
575
576 static Property scsi_generic_properties[] = {
577 DEFINE_PROP_DRIVE("drive", SCSIDevice, conf.blk),
578 DEFINE_PROP_END_OF_LIST(),
579 };
580
581 static int scsi_generic_parse_cdb(SCSIDevice *dev, SCSICommand *cmd,
582 uint8_t *buf, void *hba_private)
583 {
584 return scsi_bus_parse_cdb(dev, cmd, buf, hba_private);
585 }
586
587 static void scsi_generic_class_initfn(ObjectClass *klass, void *data)
588 {
589 DeviceClass *dc = DEVICE_CLASS(klass);
590 SCSIDeviceClass *sc = SCSI_DEVICE_CLASS(klass);
591
592 sc->realize = scsi_generic_realize;
593 sc->alloc_req = scsi_new_request;
594 sc->parse_cdb = scsi_generic_parse_cdb;
595 dc->fw_name = "disk";
596 dc->desc = "pass through generic scsi device (/dev/sg*)";
597 dc->reset = scsi_generic_reset;
598 dc->props = scsi_generic_properties;
599 dc->vmsd = &vmstate_scsi_device;
600 }
601
602 static const TypeInfo scsi_generic_info = {
603 .name = "scsi-generic",
604 .parent = TYPE_SCSI_DEVICE,
605 .instance_size = sizeof(SCSIDevice),
606 .class_init = scsi_generic_class_initfn,
607 };
608
609 static void scsi_generic_register_types(void)
610 {
611 type_register_static(&scsi_generic_info);
612 }
613
614 type_init(scsi_generic_register_types)
615
616 #endif /* __linux__ */