scsi: move handling of REQUEST SENSE to common code
[qemu/cris-port.git] / hw / scsi-bus.c
blobab45226507454ba227bca9357519e9479f95ed8c
1 #include "hw.h"
2 #include "qemu-error.h"
3 #include "scsi.h"
4 #include "scsi-defs.h"
5 #include "qdev.h"
6 #include "blockdev.h"
7 #include "trace.h"
9 static char *scsibus_get_fw_dev_path(DeviceState *dev);
10 static int scsi_req_parse(SCSICommand *cmd, SCSIDevice *dev, uint8_t *buf);
11 static int scsi_build_sense(uint8_t *in_buf, int in_len,
12 uint8_t *buf, int len, bool fixed);
14 static struct BusInfo scsi_bus_info = {
15 .name = "SCSI",
16 .size = sizeof(SCSIBus),
17 .get_fw_dev_path = scsibus_get_fw_dev_path,
18 .props = (Property[]) {
19 DEFINE_PROP_UINT32("scsi-id", SCSIDevice, id, -1),
20 DEFINE_PROP_UINT32("lun", SCSIDevice, lun, 0),
21 DEFINE_PROP_END_OF_LIST(),
24 static int next_scsi_bus;
26 /* Create a scsi bus, and attach devices to it. */
27 void scsi_bus_new(SCSIBus *bus, DeviceState *host, int tcq, int ndev,
28 const SCSIBusOps *ops)
30 qbus_create_inplace(&bus->qbus, &scsi_bus_info, host, NULL);
31 bus->busnr = next_scsi_bus++;
32 bus->tcq = tcq;
33 bus->ndev = ndev;
34 bus->ops = ops;
35 bus->qbus.allow_hotplug = 1;
38 static int scsi_qdev_init(DeviceState *qdev, DeviceInfo *base)
40 SCSIDevice *dev = DO_UPCAST(SCSIDevice, qdev, qdev);
41 SCSIDeviceInfo *info = DO_UPCAST(SCSIDeviceInfo, qdev, base);
42 SCSIBus *bus = DO_UPCAST(SCSIBus, qbus, dev->qdev.parent_bus);
43 int rc = -1;
45 if (dev->id == -1) {
46 for (dev->id = 0; dev->id < bus->ndev; dev->id++) {
47 if (bus->devs[dev->id] == NULL)
48 break;
51 if (dev->id >= bus->ndev) {
52 error_report("bad scsi device id: %d", dev->id);
53 goto err;
56 if (bus->devs[dev->id]) {
57 qdev_free(&bus->devs[dev->id]->qdev);
59 bus->devs[dev->id] = dev;
61 dev->info = info;
62 QTAILQ_INIT(&dev->requests);
63 rc = dev->info->init(dev);
64 if (rc != 0) {
65 bus->devs[dev->id] = NULL;
68 err:
69 return rc;
72 static int scsi_qdev_exit(DeviceState *qdev)
74 SCSIDevice *dev = DO_UPCAST(SCSIDevice, qdev, qdev);
75 SCSIBus *bus = DO_UPCAST(SCSIBus, qbus, dev->qdev.parent_bus);
77 assert(bus->devs[dev->id] != NULL);
78 if (bus->devs[dev->id]->info->destroy) {
79 bus->devs[dev->id]->info->destroy(bus->devs[dev->id]);
81 bus->devs[dev->id] = NULL;
82 return 0;
85 void scsi_qdev_register(SCSIDeviceInfo *info)
87 info->qdev.bus_info = &scsi_bus_info;
88 info->qdev.init = scsi_qdev_init;
89 info->qdev.unplug = qdev_simple_unplug_cb;
90 info->qdev.exit = scsi_qdev_exit;
91 qdev_register(&info->qdev);
94 /* handle legacy '-drive if=scsi,...' cmd line args */
95 SCSIDevice *scsi_bus_legacy_add_drive(SCSIBus *bus, BlockDriverState *bdrv,
96 int unit, bool removable)
98 const char *driver;
99 DeviceState *dev;
101 driver = bdrv_is_sg(bdrv) ? "scsi-generic" : "scsi-disk";
102 dev = qdev_create(&bus->qbus, driver);
103 qdev_prop_set_uint32(dev, "scsi-id", unit);
104 if (qdev_prop_exists(dev, "removable")) {
105 qdev_prop_set_bit(dev, "removable", removable);
107 if (qdev_prop_set_drive(dev, "drive", bdrv) < 0) {
108 qdev_free(dev);
109 return NULL;
111 if (qdev_init(dev) < 0)
112 return NULL;
113 return DO_UPCAST(SCSIDevice, qdev, dev);
116 int scsi_bus_legacy_handle_cmdline(SCSIBus *bus)
118 Location loc;
119 DriveInfo *dinfo;
120 int res = 0, unit;
122 loc_push_none(&loc);
123 for (unit = 0; unit < bus->ndev; unit++) {
124 dinfo = drive_get(IF_SCSI, bus->busnr, unit);
125 if (dinfo == NULL) {
126 continue;
128 qemu_opts_loc_restore(dinfo->opts);
129 if (!scsi_bus_legacy_add_drive(bus, dinfo->bdrv, unit, false)) {
130 res = -1;
131 break;
134 loc_pop(&loc);
135 return res;
138 /* SCSIReqOps implementation for invalid commands. */
140 static int32_t scsi_invalid_command(SCSIRequest *req, uint8_t *buf)
142 scsi_req_build_sense(req, SENSE_CODE(INVALID_OPCODE));
143 scsi_req_complete(req, CHECK_CONDITION);
144 return 0;
147 struct SCSIReqOps reqops_invalid_opcode = {
148 .size = sizeof(SCSIRequest),
149 .send_command = scsi_invalid_command
152 /* SCSIReqOps implementation for REPORT LUNS and for commands sent to
153 an invalid LUN. */
155 typedef struct SCSITargetReq SCSITargetReq;
157 struct SCSITargetReq {
158 SCSIRequest req;
159 int len;
160 uint8_t buf[64];
163 static void store_lun(uint8_t *outbuf, int lun)
165 if (lun < 256) {
166 outbuf[1] = lun;
167 return;
169 outbuf[1] = (lun & 255);
170 outbuf[0] = (lun >> 8) | 0x40;
173 static bool scsi_target_emulate_report_luns(SCSITargetReq *r)
175 int len;
176 if (r->req.cmd.xfer < 16) {
177 return false;
179 if (r->req.cmd.buf[2] > 2) {
180 return false;
182 len = MIN(sizeof r->buf, r->req.cmd.xfer);
183 memset(r->buf, 0, len);
184 if (r->req.dev->lun != 0) {
185 r->buf[3] = 16;
186 r->len = 24;
187 store_lun(&r->buf[16], r->req.dev->lun);
188 } else {
189 r->buf[3] = 8;
190 r->len = 16;
192 return true;
195 static bool scsi_target_emulate_inquiry(SCSITargetReq *r)
197 assert(r->req.dev->lun != r->req.lun);
198 if (r->req.cmd.buf[1] & 0x2) {
199 /* Command support data - optional, not implemented */
200 return false;
203 if (r->req.cmd.buf[1] & 0x1) {
204 /* Vital product data */
205 uint8_t page_code = r->req.cmd.buf[2];
206 if (r->req.cmd.xfer < 4) {
207 return false;
210 r->buf[r->len++] = page_code ; /* this page */
211 r->buf[r->len++] = 0x00;
213 switch (page_code) {
214 case 0x00: /* Supported page codes, mandatory */
216 int pages;
217 pages = r->len++;
218 r->buf[r->len++] = 0x00; /* list of supported pages (this page) */
219 r->buf[pages] = r->len - pages - 1; /* number of pages */
220 break;
222 default:
223 return false;
225 /* done with EVPD */
226 assert(r->len < sizeof(r->buf));
227 r->len = MIN(r->req.cmd.xfer, r->len);
228 return true;
231 /* Standard INQUIRY data */
232 if (r->req.cmd.buf[2] != 0) {
233 return false;
236 /* PAGE CODE == 0 */
237 if (r->req.cmd.xfer < 5) {
238 return -1;
241 r->len = MIN(r->req.cmd.xfer, 36);
242 memset(r->buf, 0, r->len);
243 if (r->req.lun != 0) {
244 r->buf[0] = TYPE_NO_LUN;
245 } else {
246 r->buf[0] = TYPE_NOT_PRESENT | TYPE_INACTIVE;
247 r->buf[2] = 5; /* Version */
248 r->buf[3] = 2 | 0x10; /* HiSup, response data format */
249 r->buf[4] = r->len - 5; /* Additional Length = (Len - 1) - 4 */
250 r->buf[7] = 0x10 | (r->req.bus->tcq ? 0x02 : 0); /* Sync, TCQ. */
251 memcpy(&r->buf[8], "QEMU ", 8);
252 memcpy(&r->buf[16], "QEMU TARGET ", 16);
253 strncpy((char *) &r->buf[32], QEMU_VERSION, 4);
255 return true;
258 static int32_t scsi_target_send_command(SCSIRequest *req, uint8_t *buf)
260 SCSITargetReq *r = DO_UPCAST(SCSITargetReq, req, req);
262 switch (buf[0]) {
263 case REPORT_LUNS:
264 if (!scsi_target_emulate_report_luns(r)) {
265 goto illegal_request;
267 break;
268 case INQUIRY:
269 if (!scsi_target_emulate_inquiry(r)) {
270 goto illegal_request;
272 break;
273 case REQUEST_SENSE:
274 if (req->cmd.xfer < 4) {
275 goto illegal_request;
277 r->len = scsi_device_get_sense(r->req.dev, r->buf, req->cmd.xfer,
278 (req->cmd.buf[1] & 1) == 0);
279 break;
280 default:
281 scsi_req_build_sense(req, SENSE_CODE(LUN_NOT_SUPPORTED));
282 scsi_req_complete(req, CHECK_CONDITION);
283 return 0;
284 illegal_request:
285 scsi_req_build_sense(req, SENSE_CODE(INVALID_FIELD));
286 scsi_req_complete(req, CHECK_CONDITION);
287 return 0;
290 if (!r->len) {
291 scsi_req_complete(req, GOOD);
293 return r->len;
296 static void scsi_target_read_data(SCSIRequest *req)
298 SCSITargetReq *r = DO_UPCAST(SCSITargetReq, req, req);
299 uint32_t n;
301 n = r->len;
302 if (n > 0) {
303 r->len = 0;
304 scsi_req_data(&r->req, n);
305 } else {
306 scsi_req_complete(&r->req, GOOD);
310 static uint8_t *scsi_target_get_buf(SCSIRequest *req)
312 SCSITargetReq *r = DO_UPCAST(SCSITargetReq, req, req);
314 return r->buf;
317 struct SCSIReqOps reqops_target_command = {
318 .size = sizeof(SCSITargetReq),
319 .send_command = scsi_target_send_command,
320 .read_data = scsi_target_read_data,
321 .get_buf = scsi_target_get_buf,
325 SCSIRequest *scsi_req_alloc(SCSIReqOps *reqops, SCSIDevice *d, uint32_t tag,
326 uint32_t lun, void *hba_private)
328 SCSIRequest *req;
330 req = qemu_mallocz(reqops->size);
331 req->refcount = 1;
332 req->bus = scsi_bus_from_device(d);
333 req->dev = d;
334 req->tag = tag;
335 req->lun = lun;
336 req->hba_private = hba_private;
337 req->status = -1;
338 req->sense_len = 0;
339 req->ops = reqops;
340 trace_scsi_req_alloc(req->dev->id, req->lun, req->tag);
341 return req;
344 SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, uint32_t lun,
345 uint8_t *buf, void *hba_private)
347 SCSIRequest *req;
348 SCSICommand cmd;
350 if (scsi_req_parse(&cmd, d, buf) != 0) {
351 trace_scsi_req_parse_bad(d->id, lun, tag, buf[0]);
352 req = scsi_req_alloc(&reqops_invalid_opcode, d, tag, lun, hba_private);
353 } else {
354 trace_scsi_req_parsed(d->id, lun, tag, buf[0],
355 cmd.mode, cmd.xfer);
356 if (req->cmd.lba != -1) {
357 trace_scsi_req_parsed_lba(d->id, lun, tag, buf[0],
358 cmd.lba);
361 if (lun != d->lun ||
362 buf[0] == REPORT_LUNS ||
363 buf[0] == REQUEST_SENSE) {
364 req = scsi_req_alloc(&reqops_target_command, d, tag, lun,
365 hba_private);
366 } else {
367 req = d->info->alloc_req(d, tag, lun, hba_private);
371 req->cmd = cmd;
372 return req;
375 uint8_t *scsi_req_get_buf(SCSIRequest *req)
377 return req->ops->get_buf(req);
380 int scsi_req_get_sense(SCSIRequest *req, uint8_t *buf, int len)
382 assert(len >= 14);
383 if (!req->sense_len) {
384 return 0;
386 return scsi_build_sense(req->sense, req->sense_len, buf, len, true);
389 int scsi_device_get_sense(SCSIDevice *dev, uint8_t *buf, int len, bool fixed)
391 return scsi_build_sense(dev->sense, dev->sense_len, buf, len, fixed);
394 void scsi_req_build_sense(SCSIRequest *req, SCSISense sense)
396 trace_scsi_req_build_sense(req->dev->id, req->lun, req->tag,
397 sense.key, sense.asc, sense.ascq);
398 memset(req->sense, 0, 18);
399 req->sense[0] = 0xf0;
400 req->sense[2] = sense.key;
401 req->sense[12] = sense.asc;
402 req->sense[13] = sense.ascq;
403 req->sense_len = 18;
406 int32_t scsi_req_enqueue(SCSIRequest *req)
408 int32_t rc;
410 assert(!req->enqueued);
411 scsi_req_ref(req);
412 req->enqueued = true;
413 QTAILQ_INSERT_TAIL(&req->dev->requests, req, next);
415 scsi_req_ref(req);
416 rc = req->ops->send_command(req, req->cmd.buf);
417 scsi_req_unref(req);
418 return rc;
421 static void scsi_req_dequeue(SCSIRequest *req)
423 trace_scsi_req_dequeue(req->dev->id, req->lun, req->tag);
424 if (req->enqueued) {
425 QTAILQ_REMOVE(&req->dev->requests, req, next);
426 req->enqueued = false;
427 scsi_req_unref(req);
431 static int scsi_req_length(SCSICommand *cmd, SCSIDevice *dev, uint8_t *buf)
433 switch (buf[0] >> 5) {
434 case 0:
435 cmd->xfer = buf[4];
436 cmd->len = 6;
437 /* length 0 means 256 blocks */
438 if (cmd->xfer == 0) {
439 cmd->xfer = 256;
441 break;
442 case 1:
443 case 2:
444 cmd->xfer = buf[8] | (buf[7] << 8);
445 cmd->len = 10;
446 break;
447 case 4:
448 cmd->xfer = buf[13] | (buf[12] << 8) | (buf[11] << 16) | (buf[10] << 24);
449 cmd->len = 16;
450 break;
451 case 5:
452 cmd->xfer = buf[9] | (buf[8] << 8) | (buf[7] << 16) | (buf[6] << 24);
453 cmd->len = 12;
454 break;
455 default:
456 return -1;
459 switch (buf[0]) {
460 case TEST_UNIT_READY:
461 case REWIND:
462 case START_STOP:
463 case SEEK_6:
464 case WRITE_FILEMARKS:
465 case SPACE:
466 case RESERVE:
467 case RELEASE:
468 case ERASE:
469 case ALLOW_MEDIUM_REMOVAL:
470 case VERIFY_10:
471 case SEEK_10:
472 case SYNCHRONIZE_CACHE:
473 case LOCK_UNLOCK_CACHE:
474 case LOAD_UNLOAD:
475 case SET_CD_SPEED:
476 case SET_LIMITS:
477 case WRITE_LONG_10:
478 case MOVE_MEDIUM:
479 case UPDATE_BLOCK:
480 cmd->xfer = 0;
481 break;
482 case MODE_SENSE:
483 break;
484 case WRITE_SAME_10:
485 cmd->xfer = 1;
486 break;
487 case READ_CAPACITY_10:
488 cmd->xfer = 8;
489 break;
490 case READ_BLOCK_LIMITS:
491 cmd->xfer = 6;
492 break;
493 case READ_POSITION:
494 cmd->xfer = 20;
495 break;
496 case SEND_VOLUME_TAG:
497 cmd->xfer *= 40;
498 break;
499 case MEDIUM_SCAN:
500 cmd->xfer *= 8;
501 break;
502 case WRITE_10:
503 case WRITE_VERIFY_10:
504 case WRITE_6:
505 case WRITE_12:
506 case WRITE_VERIFY_12:
507 case WRITE_16:
508 case WRITE_VERIFY_16:
509 cmd->xfer *= dev->blocksize;
510 break;
511 case READ_10:
512 case READ_6:
513 case READ_REVERSE:
514 case RECOVER_BUFFERED_DATA:
515 case READ_12:
516 case READ_16:
517 cmd->xfer *= dev->blocksize;
518 break;
519 case INQUIRY:
520 cmd->xfer = buf[4] | (buf[3] << 8);
521 break;
522 case MAINTENANCE_OUT:
523 case MAINTENANCE_IN:
524 if (dev->type == TYPE_ROM) {
525 /* GPCMD_REPORT_KEY and GPCMD_SEND_KEY from multi media commands */
526 cmd->xfer = buf[9] | (buf[8] << 8);
528 break;
530 return 0;
533 static int scsi_req_stream_length(SCSICommand *cmd, SCSIDevice *dev, uint8_t *buf)
535 switch (buf[0]) {
536 /* stream commands */
537 case READ_6:
538 case READ_REVERSE:
539 case RECOVER_BUFFERED_DATA:
540 case WRITE_6:
541 cmd->len = 6;
542 cmd->xfer = buf[4] | (buf[3] << 8) | (buf[2] << 16);
543 if (buf[1] & 0x01) { /* fixed */
544 cmd->xfer *= dev->blocksize;
546 break;
547 case REWIND:
548 case START_STOP:
549 cmd->len = 6;
550 cmd->xfer = 0;
551 break;
552 /* generic commands */
553 default:
554 return scsi_req_length(cmd, dev, buf);
556 return 0;
559 static void scsi_cmd_xfer_mode(SCSICommand *cmd)
561 switch (cmd->buf[0]) {
562 case WRITE_6:
563 case WRITE_10:
564 case WRITE_VERIFY_10:
565 case WRITE_12:
566 case WRITE_VERIFY_12:
567 case WRITE_16:
568 case WRITE_VERIFY_16:
569 case COPY:
570 case COPY_VERIFY:
571 case COMPARE:
572 case CHANGE_DEFINITION:
573 case LOG_SELECT:
574 case MODE_SELECT:
575 case MODE_SELECT_10:
576 case SEND_DIAGNOSTIC:
577 case WRITE_BUFFER:
578 case FORMAT_UNIT:
579 case REASSIGN_BLOCKS:
580 case SEARCH_EQUAL:
581 case SEARCH_HIGH:
582 case SEARCH_LOW:
583 case UPDATE_BLOCK:
584 case WRITE_LONG_10:
585 case WRITE_SAME_10:
586 case SEARCH_HIGH_12:
587 case SEARCH_EQUAL_12:
588 case SEARCH_LOW_12:
589 case MEDIUM_SCAN:
590 case SEND_VOLUME_TAG:
591 case PERSISTENT_RESERVE_OUT:
592 case MAINTENANCE_OUT:
593 cmd->mode = SCSI_XFER_TO_DEV;
594 break;
595 default:
596 if (cmd->xfer)
597 cmd->mode = SCSI_XFER_FROM_DEV;
598 else {
599 cmd->mode = SCSI_XFER_NONE;
601 break;
605 static uint64_t scsi_cmd_lba(SCSICommand *cmd)
607 uint8_t *buf = cmd->buf;
608 uint64_t lba;
610 switch (buf[0] >> 5) {
611 case 0:
612 lba = (uint64_t) buf[3] | ((uint64_t) buf[2] << 8) |
613 (((uint64_t) buf[1] & 0x1f) << 16);
614 break;
615 case 1:
616 case 2:
617 lba = (uint64_t) buf[5] | ((uint64_t) buf[4] << 8) |
618 ((uint64_t) buf[3] << 16) | ((uint64_t) buf[2] << 24);
619 break;
620 case 4:
621 lba = (uint64_t) buf[9] | ((uint64_t) buf[8] << 8) |
622 ((uint64_t) buf[7] << 16) | ((uint64_t) buf[6] << 24) |
623 ((uint64_t) buf[5] << 32) | ((uint64_t) buf[4] << 40) |
624 ((uint64_t) buf[3] << 48) | ((uint64_t) buf[2] << 56);
625 break;
626 case 5:
627 lba = (uint64_t) buf[5] | ((uint64_t) buf[4] << 8) |
628 ((uint64_t) buf[3] << 16) | ((uint64_t) buf[2] << 24);
629 break;
630 default:
631 lba = -1;
634 return lba;
637 int scsi_req_parse(SCSICommand *cmd, SCSIDevice *dev, uint8_t *buf)
639 int rc;
641 if (dev->type == TYPE_TAPE) {
642 rc = scsi_req_stream_length(cmd, dev, buf);
643 } else {
644 rc = scsi_req_length(cmd, dev, buf);
646 if (rc != 0)
647 return rc;
649 memcpy(cmd->buf, buf, cmd->len);
650 scsi_cmd_xfer_mode(cmd);
651 cmd->lba = scsi_cmd_lba(cmd);
652 return 0;
656 * Predefined sense codes
659 /* No sense data available */
660 const struct SCSISense sense_code_NO_SENSE = {
661 .key = NO_SENSE , .asc = 0x00 , .ascq = 0x00
664 /* LUN not ready, Manual intervention required */
665 const struct SCSISense sense_code_LUN_NOT_READY = {
666 .key = NOT_READY, .asc = 0x04, .ascq = 0x03
669 /* LUN not ready, Medium not present */
670 const struct SCSISense sense_code_NO_MEDIUM = {
671 .key = NOT_READY, .asc = 0x3a, .ascq = 0x00
674 /* Hardware error, internal target failure */
675 const struct SCSISense sense_code_TARGET_FAILURE = {
676 .key = HARDWARE_ERROR, .asc = 0x44, .ascq = 0x00
679 /* Illegal request, invalid command operation code */
680 const struct SCSISense sense_code_INVALID_OPCODE = {
681 .key = ILLEGAL_REQUEST, .asc = 0x20, .ascq = 0x00
684 /* Illegal request, LBA out of range */
685 const struct SCSISense sense_code_LBA_OUT_OF_RANGE = {
686 .key = ILLEGAL_REQUEST, .asc = 0x21, .ascq = 0x00
689 /* Illegal request, Invalid field in CDB */
690 const struct SCSISense sense_code_INVALID_FIELD = {
691 .key = ILLEGAL_REQUEST, .asc = 0x24, .ascq = 0x00
694 /* Illegal request, LUN not supported */
695 const struct SCSISense sense_code_LUN_NOT_SUPPORTED = {
696 .key = ILLEGAL_REQUEST, .asc = 0x25, .ascq = 0x00
699 /* Command aborted, I/O process terminated */
700 const struct SCSISense sense_code_IO_ERROR = {
701 .key = ABORTED_COMMAND, .asc = 0x00, .ascq = 0x06
704 /* Command aborted, I_T Nexus loss occurred */
705 const struct SCSISense sense_code_I_T_NEXUS_LOSS = {
706 .key = ABORTED_COMMAND, .asc = 0x29, .ascq = 0x07
709 /* Command aborted, Logical Unit failure */
710 const struct SCSISense sense_code_LUN_FAILURE = {
711 .key = ABORTED_COMMAND, .asc = 0x3e, .ascq = 0x01
715 * scsi_build_sense
717 * Convert between fixed and descriptor sense buffers
719 int scsi_build_sense(uint8_t *in_buf, int in_len,
720 uint8_t *buf, int len, bool fixed)
722 bool fixed_in;
723 SCSISense sense;
724 if (!fixed && len < 8) {
725 return 0;
728 if (in_len == 0) {
729 sense.key = NO_SENSE;
730 sense.asc = 0;
731 sense.ascq = 0;
732 } else {
733 fixed_in = (in_buf[0] & 2) == 0;
735 if (fixed == fixed_in) {
736 memcpy(buf, in_buf, MIN(len, in_len));
737 return MIN(len, in_len);
740 if (fixed_in) {
741 sense.key = in_buf[2];
742 sense.asc = in_buf[12];
743 sense.ascq = in_buf[13];
744 } else {
745 sense.key = in_buf[1];
746 sense.asc = in_buf[2];
747 sense.ascq = in_buf[3];
751 memset(buf, 0, len);
752 if (fixed) {
753 /* Return fixed format sense buffer */
754 buf[0] = 0xf0;
755 buf[2] = sense.key;
756 buf[7] = 7;
757 buf[12] = sense.asc;
758 buf[13] = sense.ascq;
759 return MIN(len, 18);
760 } else {
761 /* Return descriptor format sense buffer */
762 buf[0] = 0x72;
763 buf[1] = sense.key;
764 buf[2] = sense.asc;
765 buf[3] = sense.ascq;
766 return 8;
770 static const char *scsi_command_name(uint8_t cmd)
772 static const char *names[] = {
773 [ TEST_UNIT_READY ] = "TEST_UNIT_READY",
774 [ REWIND ] = "REWIND",
775 [ REQUEST_SENSE ] = "REQUEST_SENSE",
776 [ FORMAT_UNIT ] = "FORMAT_UNIT",
777 [ READ_BLOCK_LIMITS ] = "READ_BLOCK_LIMITS",
778 [ REASSIGN_BLOCKS ] = "REASSIGN_BLOCKS",
779 [ READ_6 ] = "READ_6",
780 [ WRITE_6 ] = "WRITE_6",
781 [ SEEK_6 ] = "SEEK_6",
782 [ READ_REVERSE ] = "READ_REVERSE",
783 [ WRITE_FILEMARKS ] = "WRITE_FILEMARKS",
784 [ SPACE ] = "SPACE",
785 [ INQUIRY ] = "INQUIRY",
786 [ RECOVER_BUFFERED_DATA ] = "RECOVER_BUFFERED_DATA",
787 [ MAINTENANCE_IN ] = "MAINTENANCE_IN",
788 [ MAINTENANCE_OUT ] = "MAINTENANCE_OUT",
789 [ MODE_SELECT ] = "MODE_SELECT",
790 [ RESERVE ] = "RESERVE",
791 [ RELEASE ] = "RELEASE",
792 [ COPY ] = "COPY",
793 [ ERASE ] = "ERASE",
794 [ MODE_SENSE ] = "MODE_SENSE",
795 [ START_STOP ] = "START_STOP",
796 [ RECEIVE_DIAGNOSTIC ] = "RECEIVE_DIAGNOSTIC",
797 [ SEND_DIAGNOSTIC ] = "SEND_DIAGNOSTIC",
798 [ ALLOW_MEDIUM_REMOVAL ] = "ALLOW_MEDIUM_REMOVAL",
799 [ READ_CAPACITY_10 ] = "READ_CAPACITY_10",
800 [ READ_10 ] = "READ_10",
801 [ WRITE_10 ] = "WRITE_10",
802 [ SEEK_10 ] = "SEEK_10",
803 [ WRITE_VERIFY_10 ] = "WRITE_VERIFY_10",
804 [ VERIFY_10 ] = "VERIFY_10",
805 [ SEARCH_HIGH ] = "SEARCH_HIGH",
806 [ SEARCH_EQUAL ] = "SEARCH_EQUAL",
807 [ SEARCH_LOW ] = "SEARCH_LOW",
808 [ SET_LIMITS ] = "SET_LIMITS",
809 [ PRE_FETCH ] = "PRE_FETCH",
810 /* READ_POSITION and PRE_FETCH use the same operation code */
811 [ SYNCHRONIZE_CACHE ] = "SYNCHRONIZE_CACHE",
812 [ LOCK_UNLOCK_CACHE ] = "LOCK_UNLOCK_CACHE",
813 [ READ_DEFECT_DATA ] = "READ_DEFECT_DATA",
814 [ MEDIUM_SCAN ] = "MEDIUM_SCAN",
815 [ COMPARE ] = "COMPARE",
816 [ COPY_VERIFY ] = "COPY_VERIFY",
817 [ WRITE_BUFFER ] = "WRITE_BUFFER",
818 [ READ_BUFFER ] = "READ_BUFFER",
819 [ UPDATE_BLOCK ] = "UPDATE_BLOCK",
820 [ READ_LONG_10 ] = "READ_LONG_10",
821 [ WRITE_LONG_10 ] = "WRITE_LONG_10",
822 [ CHANGE_DEFINITION ] = "CHANGE_DEFINITION",
823 [ WRITE_SAME_10 ] = "WRITE_SAME_10",
824 [ UNMAP ] = "UNMAP",
825 [ READ_TOC ] = "READ_TOC",
826 [ REPORT_DENSITY_SUPPORT ] = "REPORT_DENSITY_SUPPORT",
827 [ GET_CONFIGURATION ] = "GET_CONFIGURATION",
828 [ LOG_SELECT ] = "LOG_SELECT",
829 [ LOG_SENSE ] = "LOG_SENSE",
830 [ MODE_SELECT_10 ] = "MODE_SELECT_10",
831 [ RESERVE_10 ] = "RESERVE_10",
832 [ RELEASE_10 ] = "RELEASE_10",
833 [ MODE_SENSE_10 ] = "MODE_SENSE_10",
834 [ PERSISTENT_RESERVE_IN ] = "PERSISTENT_RESERVE_IN",
835 [ PERSISTENT_RESERVE_OUT ] = "PERSISTENT_RESERVE_OUT",
836 [ WRITE_FILEMARKS_16 ] = "WRITE_FILEMARKS_16",
837 [ EXTENDED_COPY ] = "EXTENDED_COPY",
838 [ ATA_PASSTHROUGH ] = "ATA_PASSTHROUGH",
839 [ ACCESS_CONTROL_IN ] = "ACCESS_CONTROL_IN",
840 [ ACCESS_CONTROL_OUT ] = "ACCESS_CONTROL_OUT",
841 [ READ_16 ] = "READ_16",
842 [ COMPARE_AND_WRITE ] = "COMPARE_AND_WRITE",
843 [ WRITE_16 ] = "WRITE_16",
844 [ WRITE_VERIFY_16 ] = "WRITE_VERIFY_16",
845 [ VERIFY_16 ] = "VERIFY_16",
846 [ SYNCHRONIZE_CACHE_16 ] = "SYNCHRONIZE_CACHE_16",
847 [ LOCATE_16 ] = "LOCATE_16",
848 [ WRITE_SAME_16 ] = "WRITE_SAME_16",
849 [ ERASE_16 ] = "ERASE_16",
850 [ SERVICE_ACTION_IN ] = "SERVICE_ACTION_IN",
851 [ WRITE_LONG_16 ] = "WRITE_LONG_16",
852 [ REPORT_LUNS ] = "REPORT_LUNS",
853 [ BLANK ] = "BLANK",
854 [ MAINTENANCE_IN ] = "MAINTENANCE_IN",
855 [ MAINTENANCE_OUT ] = "MAINTENANCE_OUT",
856 [ MOVE_MEDIUM ] = "MOVE_MEDIUM",
857 [ LOAD_UNLOAD ] = "LOAD_UNLOAD",
858 [ READ_12 ] = "READ_12",
859 [ WRITE_12 ] = "WRITE_12",
860 [ WRITE_VERIFY_12 ] = "WRITE_VERIFY_12",
861 [ VERIFY_12 ] = "VERIFY_12",
862 [ SEARCH_HIGH_12 ] = "SEARCH_HIGH_12",
863 [ SEARCH_EQUAL_12 ] = "SEARCH_EQUAL_12",
864 [ SEARCH_LOW_12 ] = "SEARCH_LOW_12",
865 [ READ_ELEMENT_STATUS ] = "READ_ELEMENT_STATUS",
866 [ SEND_VOLUME_TAG ] = "SEND_VOLUME_TAG",
867 [ READ_DEFECT_DATA_12 ] = "READ_DEFECT_DATA_12",
868 [ SET_CD_SPEED ] = "SET_CD_SPEED",
871 if (cmd >= ARRAY_SIZE(names) || names[cmd] == NULL)
872 return "*UNKNOWN*";
873 return names[cmd];
876 SCSIRequest *scsi_req_ref(SCSIRequest *req)
878 req->refcount++;
879 return req;
882 void scsi_req_unref(SCSIRequest *req)
884 if (--req->refcount == 0) {
885 if (req->ops->free_req) {
886 req->ops->free_req(req);
888 qemu_free(req);
892 /* Tell the device that we finished processing this chunk of I/O. It
893 will start the next chunk or complete the command. */
894 void scsi_req_continue(SCSIRequest *req)
896 trace_scsi_req_continue(req->dev->id, req->lun, req->tag);
897 if (req->cmd.mode == SCSI_XFER_TO_DEV) {
898 req->ops->write_data(req);
899 } else {
900 req->ops->read_data(req);
904 /* Called by the devices when data is ready for the HBA. The HBA should
905 start a DMA operation to read or fill the device's data buffer.
906 Once it completes, calling scsi_req_continue will restart I/O. */
907 void scsi_req_data(SCSIRequest *req, int len)
909 trace_scsi_req_data(req->dev->id, req->lun, req->tag, len);
910 req->bus->ops->transfer_data(req, len);
913 void scsi_req_print(SCSIRequest *req)
915 FILE *fp = stderr;
916 int i;
918 fprintf(fp, "[%s id=%d] %s",
919 req->dev->qdev.parent_bus->name,
920 req->dev->id,
921 scsi_command_name(req->cmd.buf[0]));
922 for (i = 1; i < req->cmd.len; i++) {
923 fprintf(fp, " 0x%02x", req->cmd.buf[i]);
925 switch (req->cmd.mode) {
926 case SCSI_XFER_NONE:
927 fprintf(fp, " - none\n");
928 break;
929 case SCSI_XFER_FROM_DEV:
930 fprintf(fp, " - from-dev len=%zd\n", req->cmd.xfer);
931 break;
932 case SCSI_XFER_TO_DEV:
933 fprintf(fp, " - to-dev len=%zd\n", req->cmd.xfer);
934 break;
935 default:
936 fprintf(fp, " - Oops\n");
937 break;
941 void scsi_req_complete(SCSIRequest *req, int status)
943 assert(req->status == -1);
944 req->status = status;
946 assert(req->sense_len < sizeof(req->sense));
947 if (status == GOOD) {
948 req->sense_len = 0;
951 if (req->sense_len) {
952 memcpy(req->dev->sense, req->sense, req->sense_len);
954 req->dev->sense_len = req->sense_len;
956 scsi_req_ref(req);
957 scsi_req_dequeue(req);
958 req->bus->ops->complete(req, req->status);
959 scsi_req_unref(req);
962 void scsi_req_cancel(SCSIRequest *req)
964 if (req->ops->cancel_io) {
965 req->ops->cancel_io(req);
967 scsi_req_ref(req);
968 scsi_req_dequeue(req);
969 if (req->bus->ops->cancel) {
970 req->bus->ops->cancel(req);
972 scsi_req_unref(req);
975 void scsi_req_abort(SCSIRequest *req, int status)
977 if (req->ops->cancel_io) {
978 req->ops->cancel_io(req);
980 scsi_req_complete(req, status);
983 void scsi_device_purge_requests(SCSIDevice *sdev)
985 SCSIRequest *req;
987 while (!QTAILQ_EMPTY(&sdev->requests)) {
988 req = QTAILQ_FIRST(&sdev->requests);
989 scsi_req_cancel(req);
993 static char *scsibus_get_fw_dev_path(DeviceState *dev)
995 SCSIDevice *d = DO_UPCAST(SCSIDevice, qdev, dev);
996 SCSIBus *bus = scsi_bus_from_device(d);
997 char path[100];
998 int i;
1000 for (i = 0; i < bus->ndev; i++) {
1001 if (bus->devs[i] == d) {
1002 break;
1006 assert(i != bus->ndev);
1008 snprintf(path, sizeof(path), "%s@%x", qdev_fw_name(dev), i);
1010 return strdup(path);