1
2
3
4
5
6
7
8
9
10
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
25
26#ifdef DEBUG_SCSI
27#define DPRINTF(fmt, ...) \
28do { printf("scsi-generic: " fmt , ## __VA_ARGS__); } while (0)
29#else
30#define DPRINTF(fmt, ...) do {} while(0)
31#endif
32
33#define BADF(fmt, ...) \
34do { 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
51typedef 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
59static 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
70static 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
81static void scsi_free_request(SCSIRequest *req)
82{
83 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
84
85 g_free(r->buf);
86}
87
88
89static 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);
139done:
140 scsi_req_unref(&r->req);
141}
142
143static 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
152static 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
176static 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
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
212
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 if (s->type == TYPE_DISK &&
226 r->req.cmd.buf[0] == INQUIRY &&
227 r->req.cmd.buf[2] == 0xb0) {
228 uint32_t max_transfer =
229 blk_get_max_transfer(s->conf.blk) / s->blocksize;
230
231 assert(max_transfer);
232 stl_be_p(&r->buf[8], max_transfer);
233
234 if (ldl_be_p(&r->buf[12]) > max_transfer) {
235 stl_be_p(&r->buf[12], max_transfer);
236 }
237 }
238 scsi_req_data(&r->req, len);
239 scsi_req_unref(&r->req);
240}
241
242
243static void scsi_read_data(SCSIRequest *req)
244{
245 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
246 SCSIDevice *s = r->req.dev;
247 int ret;
248
249 DPRINTF("scsi_read_data 0x%x\n", req->tag);
250
251
252 scsi_req_ref(&r->req);
253 if (r->len == -1) {
254 scsi_command_complete_noio(r, 0);
255 return;
256 }
257
258 ret = execute_command(s->conf.blk, r, SG_DXFER_FROM_DEV,
259 scsi_read_complete);
260 if (ret < 0) {
261 scsi_command_complete_noio(r, ret);
262 }
263}
264
265static void scsi_write_complete(void * opaque, int ret)
266{
267 SCSIGenericReq *r = (SCSIGenericReq *)opaque;
268 SCSIDevice *s = r->req.dev;
269
270 DPRINTF("scsi_write_complete() ret = %d\n", ret);
271
272 assert(r->req.aiocb != NULL);
273 r->req.aiocb = NULL;
274
275 if (ret || r->req.io_canceled) {
276 scsi_command_complete_noio(r, ret);
277 return;
278 }
279
280 if (r->req.cmd.buf[0] == MODE_SELECT && r->req.cmd.buf[4] == 12 &&
281 s->type == TYPE_TAPE) {
282 s->blocksize = (r->buf[9] << 16) | (r->buf[10] << 8) | r->buf[11];
283 DPRINTF("block size %d\n", s->blocksize);
284 }
285
286 scsi_command_complete_noio(r, ret);
287}
288
289
290
291static void scsi_write_data(SCSIRequest *req)
292{
293 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
294 SCSIDevice *s = r->req.dev;
295 int ret;
296
297 DPRINTF("scsi_write_data 0x%x\n", req->tag);
298 if (r->len == 0) {
299 r->len = r->buflen;
300 scsi_req_data(&r->req, r->len);
301 return;
302 }
303
304
305 scsi_req_ref(&r->req);
306 ret = execute_command(s->conf.blk, r, SG_DXFER_TO_DEV, scsi_write_complete);
307 if (ret < 0) {
308 scsi_command_complete_noio(r, ret);
309 }
310}
311
312
313static uint8_t *scsi_get_buf(SCSIRequest *req)
314{
315 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
316
317 return r->buf;
318}
319
320
321
322
323
324
325static int32_t scsi_send_command(SCSIRequest *req, uint8_t *cmd)
326{
327 SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
328 SCSIDevice *s = r->req.dev;
329 int ret;
330
331#ifdef DEBUG_SCSI
332 {
333 int i;
334 for (i = 1; i < r->req.cmd.len; i++) {
335 printf(" 0x%02x", cmd[i]);
336 }
337 printf("\n");
338 }
339#endif
340
341 if (r->req.cmd.xfer == 0) {
342 g_free(r->buf);
343 r->buflen = 0;
344 r->buf = NULL;
345
346 scsi_req_ref(&r->req);
347 ret = execute_command(s->conf.blk, r, SG_DXFER_NONE,
348 scsi_command_complete);
349 if (ret < 0) {
350 scsi_command_complete_noio(r, ret);
351 return 0;
352 }
353 return 0;
354 }
355
356 if (r->buflen != r->req.cmd.xfer) {
357 g_free(r->buf);
358 r->buf = g_malloc(r->req.cmd.xfer);
359 r->buflen = r->req.cmd.xfer;
360 }
361
362 memset(r->buf, 0, r->buflen);
363 r->len = r->req.cmd.xfer;
364 if (r->req.cmd.mode == SCSI_XFER_TO_DEV) {
365 r->len = 0;
366 return -r->req.cmd.xfer;
367 } else {
368 return r->req.cmd.xfer;
369 }
370}
371
372static int read_naa_id(const uint8_t *p, uint64_t *p_wwn)
373{
374 int i;
375
376 if ((p[1] & 0xF) == 3) {
377
378 if (p[3] != 8) {
379 return -EINVAL;
380 }
381 *p_wwn = ldq_be_p(p + 4);
382 return 0;
383 }
384
385 if ((p[1] & 0xF) == 8) {
386
387 if (p[3] < 20 || memcmp(&p[4], "naa.", 4)) {
388 return -EINVAL;
389 }
390 if (p[3] > 20 && p[24] != ',') {
391 return -EINVAL;
392 }
393 *p_wwn = 0;
394 for (i = 8; i < 24; i++) {
395 char c = toupper(p[i]);
396 c -= (c >= '0' && c <= '9' ? '0' : 'A' - 10);
397 *p_wwn = (*p_wwn << 4) | c;
398 }
399 return 0;
400 }
401
402 return -EINVAL;
403}
404
405void scsi_generic_read_device_identification(SCSIDevice *s)
406{
407 uint8_t cmd[6];
408 uint8_t buf[250];
409 uint8_t sensebuf[8];
410 sg_io_hdr_t io_header;
411 int ret;
412 int i, len;
413
414 memset(cmd, 0, sizeof(cmd));
415 memset(buf, 0, sizeof(buf));
416 cmd[0] = INQUIRY;
417 cmd[1] = 1;
418 cmd[2] = 0x83;
419 cmd[4] = sizeof(buf);
420
421 memset(&io_header, 0, sizeof(io_header));
422 io_header.interface_id = 'S';
423 io_header.dxfer_direction = SG_DXFER_FROM_DEV;
424 io_header.dxfer_len = sizeof(buf);
425 io_header.dxferp = buf;
426 io_header.cmdp = cmd;
427 io_header.cmd_len = sizeof(cmd);
428 io_header.mx_sb_len = sizeof(sensebuf);
429 io_header.sbp = sensebuf;
430 io_header.timeout = 6000;
431
432 ret = blk_ioctl(s->conf.blk, SG_IO, &io_header);
433 if (ret < 0 || io_header.driver_status || io_header.host_status) {
434 return;
435 }
436
437 len = MIN((buf[2] << 8) | buf[3], sizeof(buf) - 4);
438 for (i = 0; i + 3 <= len; ) {
439 const uint8_t *p = &buf[i + 4];
440 uint64_t wwn;
441
442 if (i + (p[3] + 4) > len) {
443 break;
444 }
445
446 if ((p[1] & 0x10) == 0) {
447
448 if (read_naa_id(p, &wwn) == 0) {
449 s->wwn = wwn;
450 }
451 } else if ((p[1] & 0x10) == 0x10) {
452
453 if (read_naa_id(p, &wwn) == 0) {
454 s->port_wwn = wwn;
455 }
456 }
457
458 i += p[3] + 4;
459 }
460}
461
462static int get_stream_blocksize(BlockBackend *blk)
463{
464 uint8_t cmd[6];
465 uint8_t buf[12];
466 uint8_t sensebuf[8];
467 sg_io_hdr_t io_header;
468 int ret;
469
470 memset(cmd, 0, sizeof(cmd));
471 memset(buf, 0, sizeof(buf));
472 cmd[0] = MODE_SENSE;
473 cmd[4] = sizeof(buf);
474
475 memset(&io_header, 0, sizeof(io_header));
476 io_header.interface_id = 'S';
477 io_header.dxfer_direction = SG_DXFER_FROM_DEV;
478 io_header.dxfer_len = sizeof(buf);
479 io_header.dxferp = buf;
480 io_header.cmdp = cmd;
481 io_header.cmd_len = sizeof(cmd);
482 io_header.mx_sb_len = sizeof(sensebuf);
483 io_header.sbp = sensebuf;
484 io_header.timeout = 6000;
485
486 ret = blk_ioctl(blk, SG_IO, &io_header);
487 if (ret < 0 || io_header.driver_status || io_header.host_status) {
488 return -1;
489 }
490 return (buf[9] << 16) | (buf[10] << 8) | buf[11];
491}
492
493static void scsi_generic_reset(DeviceState *dev)
494{
495 SCSIDevice *s = SCSI_DEVICE(dev);
496
497 scsi_device_purge_requests(s, SENSE_CODE(RESET));
498}
499
500static void scsi_generic_realize(SCSIDevice *s, Error **errp)
501{
502 int rc;
503 int sg_version;
504 struct sg_scsi_id scsiid;
505
506 if (!s->conf.blk) {
507 error_setg(errp, "drive property not set");
508 return;
509 }
510
511 if (blk_get_on_error(s->conf.blk, 0) != BLOCKDEV_ON_ERROR_ENOSPC) {
512 error_setg(errp, "Device doesn't support drive option werror");
513 return;
514 }
515 if (blk_get_on_error(s->conf.blk, 1) != BLOCKDEV_ON_ERROR_REPORT) {
516 error_setg(errp, "Device doesn't support drive option rerror");
517 return;
518 }
519
520
521 rc = blk_ioctl(s->conf.blk, SG_GET_VERSION_NUM, &sg_version);
522 if (rc < 0) {
523 error_setg(errp, "cannot get SG_IO version number: %s. "
524 "Is this a SCSI device?",
525 strerror(-rc));
526 return;
527 }
528 if (sg_version < 30000) {
529 error_setg(errp, "scsi generic interface too old");
530 return;
531 }
532
533
534 if (blk_ioctl(s->conf.blk, SG_GET_SCSI_ID, &scsiid)) {
535 error_setg(errp, "SG_GET_SCSI_ID ioctl failed");
536 return;
537 }
538
539
540 s->type = scsiid.scsi_type;
541 DPRINTF("device type %d\n", s->type);
542
543 switch (s->type) {
544 case TYPE_TAPE:
545 s->blocksize = get_stream_blocksize(s->conf.blk);
546 if (s->blocksize == -1) {
547 s->blocksize = 0;
548 }
549 break;
550
551
552
553
554
555 case TYPE_ROM:
556 case TYPE_WORM:
557 s->blocksize = 2048;
558 break;
559 default:
560 s->blocksize = 512;
561 break;
562 }
563
564 DPRINTF("block size %d\n", s->blocksize);
565
566 scsi_generic_read_device_identification(s);
567}
568
569const SCSIReqOps scsi_generic_req_ops = {
570 .size = sizeof(SCSIGenericReq),
571 .free_req = scsi_free_request,
572 .send_command = scsi_send_command,
573 .read_data = scsi_read_data,
574 .write_data = scsi_write_data,
575 .get_buf = scsi_get_buf,
576 .load_request = scsi_generic_load_request,
577 .save_request = scsi_generic_save_request,
578};
579
580static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun,
581 uint8_t *buf, void *hba_private)
582{
583 return scsi_req_alloc(&scsi_generic_req_ops, d, tag, lun, hba_private);
584}
585
586static Property scsi_generic_properties[] = {
587 DEFINE_PROP_DRIVE("drive", SCSIDevice, conf.blk),
588 DEFINE_PROP_END_OF_LIST(),
589};
590
591static int scsi_generic_parse_cdb(SCSIDevice *dev, SCSICommand *cmd,
592 uint8_t *buf, void *hba_private)
593{
594 return scsi_bus_parse_cdb(dev, cmd, buf, hba_private);
595}
596
597static void scsi_generic_class_initfn(ObjectClass *klass, void *data)
598{
599 DeviceClass *dc = DEVICE_CLASS(klass);
600 SCSIDeviceClass *sc = SCSI_DEVICE_CLASS(klass);
601
602 sc->realize = scsi_generic_realize;
603 sc->alloc_req = scsi_new_request;
604 sc->parse_cdb = scsi_generic_parse_cdb;
605 dc->fw_name = "disk";
606 dc->desc = "pass through generic scsi device (/dev/sg*)";
607 dc->reset = scsi_generic_reset;
608 dc->props = scsi_generic_properties;
609 dc->vmsd = &vmstate_scsi_device;
610}
611
612static const TypeInfo scsi_generic_info = {
613 .name = "scsi-generic",
614 .parent = TYPE_SCSI_DEVICE,
615 .instance_size = sizeof(SCSIDevice),
616 .class_init = scsi_generic_class_initfn,
617};
618
619static void scsi_generic_register_types(void)
620{
621 type_register_static(&scsi_generic_info);
622}
623
624type_init(scsi_generic_register_types)
625
626#endif
627