Lines Matching +full:sense +full:- +full:mode
3 #include "qemu/error-report.h"
6 #include "qemu/hw-version.h"
7 #include "hw/qdev-properties.h"
9 #include "migration/qemu-file-types.h"
12 #include "sysemu/block-backend.h"
36 QTAILQ_FOREACH_RCU(kid, &bus->qbus.children, sibling) { in do_scsi_device_find()
37 DeviceState *qdev = kid->child; in do_scsi_device_find()
40 if (dev->channel == channel && dev->id == id) { in do_scsi_device_find()
41 if (dev->lun == lun) { in do_scsi_device_find()
59 * main thread hot-plugging the device. in do_scsi_device_find()
64 if (retval && !include_unrealized && !qdev_is_realized(&retval->qdev)) { in do_scsi_device_find()
91 * vmstate ->put(), use scsi_device_for_each_req_async() for other cases.
103 QTAILQ_FOREACH_SAFE(req, &s->requests, next, next_req) { in scsi_device_for_each_req_sync()
117 SCSIDevice *s = data->s; in scsi_device_for_each_req_async_bh()
126 * we have the in-flight counter incremented, that drain must block. in scsi_device_for_each_req_async_bh()
128 ctx = blk_get_aio_context(s->conf.blk); in scsi_device_for_each_req_async_bh()
131 QTAILQ_FOREACH_SAFE(req, &s->requests, next, next) { in scsi_device_for_each_req_async_bh()
132 data->fn(req, data->fn_opaque); in scsi_device_for_each_req_async_bh()
139 blk_dec_in_flight(s->conf.blk); in scsi_device_for_each_req_async_bh()
145 * Keeps the BlockBackend's in-flight counter incremented until everything is
157 data->s = s; in scsi_device_for_each_req_async()
158 data->fn = fn; in scsi_device_for_each_req_async()
159 data->fn_opaque = opaque; in scsi_device_for_each_req_async()
168 blk_inc_in_flight(s->conf.blk); in scsi_device_for_each_req_async()
169 aio_bh_schedule_oneshot(blk_get_aio_context(s->conf.blk), in scsi_device_for_each_req_async()
177 if (sc->realize) { in scsi_device_realize()
178 sc->realize(s, errp); in scsi_device_realize()
185 if (sc->unrealize) { in scsi_device_unrealize()
186 sc->unrealize(s); in scsi_device_unrealize()
193 SCSIBus *bus = DO_UPCAST(SCSIBus, qbus, dev->qdev.parent_bus); in scsi_bus_parse_cdb()
196 assert(cmd->len == 0); in scsi_bus_parse_cdb()
198 if (bus->info->parse_cdb) { in scsi_bus_parse_cdb()
199 rc = bus->info->parse_cdb(dev, cmd, buf, buf_len, hba_private); in scsi_bus_parse_cdb()
208 if (sc->alloc_req) { in scsi_device_alloc_req()
209 return sc->alloc_req(s, tag, lun, buf, hba_private); in scsi_device_alloc_req()
218 if (sc->unit_attention_reported) { in scsi_device_unit_attention_reported()
219 sc->unit_attention_reported(s); in scsi_device_unit_attention_reported()
228 bus->busnr = next_scsi_bus++; in scsi_bus_init_named()
229 bus->info = info; in scsi_bus_init_named()
235 req->retry = true; in scsi_req_retry()
242 if (req->retry) { in scsi_dma_restart_req()
243 req->retry = false; in scsi_dma_restart_req()
244 switch (req->cmd.mode) { in scsi_dma_restart_req()
279 if (d && d->lun == lun) { in scsi_bus_is_address_free()
296 if (dev->channel > bus->info->max_channel) { in scsi_bus_check_address()
297 error_setg(errp, "bad scsi channel id: %d", dev->channel); in scsi_bus_check_address()
300 if (dev->id != -1 && dev->id > bus->info->max_target) { in scsi_bus_check_address()
301 error_setg(errp, "bad scsi device id: %d", dev->id); in scsi_bus_check_address()
304 if (dev->lun != -1 && dev->lun > bus->info->max_lun) { in scsi_bus_check_address()
305 error_setg(errp, "bad scsi device lun: %d", dev->lun); in scsi_bus_check_address()
309 if (dev->id != -1 && dev->lun != -1) { in scsi_bus_check_address()
311 if (!scsi_bus_is_address_free(bus, dev->channel, dev->id, dev->lun, &d)) { in scsi_bus_check_address()
312 error_setg(errp, "lun already used by '%s'", d->qdev.id); in scsi_bus_check_address()
323 SCSIBus *bus = DO_UPCAST(SCSIBus, qbus, dev->qdev.parent_bus); in scsi_qdev_realize()
327 if (dev->id == -1) { in scsi_qdev_realize()
328 int id = -1; in scsi_qdev_realize()
329 if (dev->lun == -1) { in scsi_qdev_realize()
330 dev->lun = 0; in scsi_qdev_realize()
333 is_free = scsi_bus_is_address_free(bus, dev->channel, ++id, dev->lun, NULL); in scsi_qdev_realize()
334 } while (!is_free && id < bus->info->max_target); in scsi_qdev_realize()
339 dev->id = id; in scsi_qdev_realize()
340 } else if (dev->lun == -1) { in scsi_qdev_realize()
341 int lun = -1; in scsi_qdev_realize()
343 is_free = scsi_bus_is_address_free(bus, dev->channel, dev->id, ++lun, NULL); in scsi_qdev_realize()
344 } while (!is_free && lun < bus->info->max_lun); in scsi_qdev_realize()
349 dev->lun = lun; in scsi_qdev_realize()
352 QTAILQ_INIT(&dev->requests); in scsi_qdev_realize()
358 dev->vmsentry = qdev_add_vm_change_state_handler(DEVICE(dev), in scsi_qdev_realize()
366 if (dev->vmsentry) { in scsi_qdev_unrealize()
367 qemu_del_vm_change_state_handler(dev->vmsentry); in scsi_qdev_unrealize()
374 blockdev_mark_auto_del(dev->conf.blk); in scsi_qdev_unrealize()
377 /* handle legacy '-drive if=scsi,...' cmd line args */
390 driver = "scsi-generic"; in scsi_bus_legacy_add_drive()
393 if (dinfo && dinfo->media_cd) { in scsi_bus_legacy_add_drive()
394 driver = "scsi-cd"; in scsi_bus_legacy_add_drive()
396 driver = "scsi-hd"; in scsi_bus_legacy_add_drive()
405 s->conf = *conf; in scsi_bus_legacy_add_drive()
407 check_boot_index(conf->bootindex, &local_err); in scsi_bus_legacy_add_drive()
413 add_boot_device_path(conf->bootindex, dev, NULL); in scsi_bus_legacy_add_drive()
415 qdev_prop_set_uint32(dev, "scsi-id", unit); in scsi_bus_legacy_add_drive()
427 if (!qdev_realize_and_unref(dev, &bus->qbus, errp)) { in scsi_bus_legacy_add_drive()
440 .bootindex = -1, in scsi_bus_legacy_handle_cmdline()
447 for (unit = 0; unit <= bus->info->max_target; unit++) { in scsi_bus_legacy_handle_cmdline()
448 dinfo = drive_get(IF_SCSI, bus->busnr, unit); in scsi_bus_legacy_handle_cmdline()
452 qemu_opts_loc_restore(dinfo->opts); in scsi_bus_legacy_handle_cmdline()
491 if (req->dev->unit_attention.key == UNIT_ATTENTION) { in scsi_fetch_unit_attention_sense()
492 ua = &req->dev->unit_attention; in scsi_fetch_unit_attention_sense()
493 } else if (req->bus->unit_attention.key == UNIT_ATTENTION) { in scsi_fetch_unit_attention_sense()
494 ua = &req->bus->unit_attention; in scsi_fetch_unit_attention_sense()
498 * Fetch the unit attention sense immediately so that another in scsi_fetch_unit_attention_sense()
552 if (r->req.cmd.xfer < 16) { in scsi_target_emulate_report_luns()
555 if (r->req.cmd.buf[2] > 2) { in scsi_target_emulate_report_luns()
562 channel = r->req.dev->channel; in scsi_target_emulate_report_luns()
563 id = r->req.dev->id; in scsi_target_emulate_report_luns()
574 QTAILQ_FOREACH_RCU(kid, &r->req.bus->qbus.children, sibling) { in scsi_target_emulate_report_luns()
575 DeviceState *qdev = kid->child; in scsi_target_emulate_report_luns()
578 if (dev->channel == channel && dev->id == id && dev->lun != 0 && in scsi_target_emulate_report_luns()
579 qdev_is_realized(&dev->qdev)) { in scsi_target_emulate_report_luns()
580 store_lun(tmp, dev->lun); in scsi_target_emulate_report_luns()
587 r->buf_len = len; in scsi_target_emulate_report_luns()
588 r->buf = g_byte_array_free(buf, FALSE); in scsi_target_emulate_report_luns()
589 r->len = MIN(len, r->req.cmd.xfer & ~7); in scsi_target_emulate_report_luns()
592 stl_be_p(&r->buf[0], len - 8); in scsi_target_emulate_report_luns()
597 * with an additional sense code of REPORTED LUNS DATA HAS CHANGED. in scsi_target_emulate_report_luns()
599 scsi_clear_reported_luns_changed(&r->req); in scsi_target_emulate_report_luns()
606 assert(r->req.dev->lun != r->req.lun); in scsi_target_emulate_inquiry()
608 scsi_target_alloc_buf(&r->req, SCSI_INQUIRY_LEN); in scsi_target_emulate_inquiry()
610 if (r->req.cmd.buf[1] & 0x2) { in scsi_target_emulate_inquiry()
611 /* Command support data - optional, not implemented */ in scsi_target_emulate_inquiry()
615 if (r->req.cmd.buf[1] & 0x1) { in scsi_target_emulate_inquiry()
617 uint8_t page_code = r->req.cmd.buf[2]; in scsi_target_emulate_inquiry()
618 r->buf[r->len++] = page_code ; /* this page */ in scsi_target_emulate_inquiry()
619 r->buf[r->len++] = 0x00; in scsi_target_emulate_inquiry()
625 pages = r->len++; in scsi_target_emulate_inquiry()
626 r->buf[r->len++] = 0x00; /* list of supported pages (this page) */ in scsi_target_emulate_inquiry()
627 r->buf[pages] = r->len - pages - 1; /* number of pages */ in scsi_target_emulate_inquiry()
634 assert(r->len < r->buf_len); in scsi_target_emulate_inquiry()
635 r->len = MIN(r->req.cmd.xfer, r->len); in scsi_target_emulate_inquiry()
640 if (r->req.cmd.buf[2] != 0) { in scsi_target_emulate_inquiry()
645 r->len = MIN(r->req.cmd.xfer, SCSI_INQUIRY_LEN); in scsi_target_emulate_inquiry()
646 memset(r->buf, 0, r->len); in scsi_target_emulate_inquiry()
647 if (r->req.lun != 0) { in scsi_target_emulate_inquiry()
648 r->buf[0] = TYPE_NO_LUN; in scsi_target_emulate_inquiry()
650 r->buf[0] = TYPE_NOT_PRESENT | TYPE_INACTIVE; in scsi_target_emulate_inquiry()
651 r->buf[2] = 5; /* Version */ in scsi_target_emulate_inquiry()
652 r->buf[3] = 2 | 0x10; /* HiSup, response data format */ in scsi_target_emulate_inquiry()
653 r->buf[4] = r->len - 5; /* Additional Length = (Len - 1) - 4 */ in scsi_target_emulate_inquiry()
654 r->buf[7] = 0x10 | (r->req.bus->info->tcq ? 0x02 : 0); /* Sync, TCQ. */ in scsi_target_emulate_inquiry()
655 memcpy(&r->buf[8], "QEMU ", 8); in scsi_target_emulate_inquiry()
656 memcpy(&r->buf[16], "QEMU TARGET ", 16); in scsi_target_emulate_inquiry()
657 pstrcpy((char *) &r->buf[32], 4, qemu_hw_version()); in scsi_target_emulate_inquiry()
664 if (req->dev->type == TYPE_SCANNER) in scsi_sense_len()
673 int fixed_sense = (req->cmd.buf[1] & 1) == 0; in scsi_target_send_command()
675 if (req->lun != 0 && in scsi_target_send_command()
693 scsi_target_alloc_buf(&r->req, scsi_sense_len(req)); in scsi_target_send_command()
694 if (req->lun != 0) { in scsi_target_send_command()
695 const struct SCSISense sense = SENSE_CODE(LUN_NOT_SUPPORTED); in scsi_target_send_command() local
697 r->len = scsi_build_sense_buf(r->buf, req->cmd.xfer, in scsi_target_send_command()
698 sense, fixed_sense); in scsi_target_send_command()
700 r->len = scsi_device_get_sense(r->req.dev, r->buf, in scsi_target_send_command()
701 MIN(req->cmd.xfer, r->buf_len), in scsi_target_send_command()
704 if (r->req.dev->sense_is_ua) { in scsi_target_send_command()
705 scsi_device_unit_attention_reported(req->dev); in scsi_target_send_command()
706 r->req.dev->sense_len = 0; in scsi_target_send_command()
707 r->req.dev->sense_is_ua = false; in scsi_target_send_command()
722 if (!r->len) { in scsi_target_send_command()
725 return r->len; in scsi_target_send_command()
733 n = r->len; in scsi_target_read_data()
735 r->len = 0; in scsi_target_read_data()
736 scsi_req_data(&r->req, n); in scsi_target_read_data()
738 scsi_req_complete(&r->req, GOOD); in scsi_target_read_data()
746 return r->buf; in scsi_target_get_buf()
753 r->buf = g_malloc(len); in scsi_target_alloc_buf()
754 r->buf_len = len; in scsi_target_alloc_buf()
756 return r->buf; in scsi_target_alloc_buf()
763 g_free(r->buf); in scsi_target_free_buf()
781 const int memset_off = offsetof(SCSIRequest, sense) in scsi_req_alloc()
782 + sizeof(req->sense); in scsi_req_alloc()
784 req = g_malloc(reqops->size); in scsi_req_alloc()
785 memset((uint8_t *)req + memset_off, 0, reqops->size - memset_off); in scsi_req_alloc()
786 req->refcount = 1; in scsi_req_alloc()
787 req->bus = bus; in scsi_req_alloc()
788 req->dev = d; in scsi_req_alloc()
789 req->tag = tag; in scsi_req_alloc()
790 req->lun = lun; in scsi_req_alloc()
791 req->hba_private = hba_private; in scsi_req_alloc()
792 req->status = -1; in scsi_req_alloc()
793 req->host_status = -1; in scsi_req_alloc()
794 req->ops = reqops; in scsi_req_alloc()
796 object_ref(OBJECT(qbus->parent)); in scsi_req_alloc()
797 notifier_list_init(&req->cancel_notifiers); in scsi_req_alloc()
799 if (reqops->init_req) { in scsi_req_alloc()
800 reqops->init_req(req); in scsi_req_alloc()
803 trace_scsi_req_alloc(req->dev->id, req->lun, req->tag); in scsi_req_alloc()
810 SCSIBus *bus = DO_UPCAST(SCSIBus, qbus, d->qdev.parent_bus); in scsi_req_new()
818 trace_scsi_req_parse_bad(d->id, lun, tag, 0); in scsi_req_new()
822 if ((d->unit_attention.key == UNIT_ATTENTION || in scsi_req_new()
823 bus->unit_attention.key == UNIT_ATTENTION) && in scsi_req_new()
833 !(buf[0] == REQUEST_SENSE && d->sense_is_ua))) { in scsi_req_new()
835 } else if (lun != d->lun || in scsi_req_new()
837 (buf[0] == REQUEST_SENSE && d->sense_len)) { in scsi_req_new()
843 if (ops != NULL || !sc->parse_cdb) { in scsi_req_new()
846 ret = sc->parse_cdb(d, &cmd, buf, buf_len, hba_private); in scsi_req_new()
850 trace_scsi_req_parse_bad(d->id, lun, tag, buf[0]); in scsi_req_new()
855 trace_scsi_req_parsed(d->id, lun, tag, buf[0], in scsi_req_new()
856 cmd.mode, cmd.xfer); in scsi_req_new()
857 if (cmd.lba != -1) { in scsi_req_new()
858 trace_scsi_req_parsed_lba(d->id, lun, tag, buf[0], in scsi_req_new()
871 req->cmd = cmd; in scsi_req_new()
872 req->residual = req->cmd.xfer; in scsi_req_new()
876 trace_scsi_inquiry(d->id, lun, tag, cmd.buf[1], cmd.buf[2]); in scsi_req_new()
879 trace_scsi_test_unit_ready(d->id, lun, tag); in scsi_req_new()
882 trace_scsi_report_luns(d->id, lun, tag); in scsi_req_new()
885 trace_scsi_request_sense(d->id, lun, tag); in scsi_req_new()
896 return req->ops->get_buf(req); in scsi_req_get_buf()
903 if (req->dev->unit_attention.key == UNIT_ATTENTION) { in scsi_clear_reported_luns_changed()
904 ua = &req->dev->unit_attention; in scsi_clear_reported_luns_changed()
905 } else if (req->bus->unit_attention.key == UNIT_ATTENTION) { in scsi_clear_reported_luns_changed()
906 ua = &req->bus->unit_attention; in scsi_clear_reported_luns_changed()
911 if (ua->asc == SENSE_CODE(REPORTED_LUNS_CHANGED).asc && in scsi_clear_reported_luns_changed()
912 ua->ascq == SENSE_CODE(REPORTED_LUNS_CHANGED).ascq) { in scsi_clear_reported_luns_changed()
922 if (!req->sense_len) { in scsi_req_get_sense()
926 ret = scsi_convert_sense(req->sense, req->sense_len, buf, len, true); in scsi_req_get_sense()
930 * only if the UA_INTLCK_CTRL field in the Control mode page is set to 00b in scsi_req_get_sense()
931 * (SAM-5, 5.14). in scsi_req_get_sense()
937 if (req->dev->sense_is_ua) { in scsi_req_get_sense()
938 scsi_device_unit_attention_reported(req->dev); in scsi_req_get_sense()
939 req->dev->sense_len = 0; in scsi_req_get_sense()
940 req->dev->sense_is_ua = false; in scsi_req_get_sense()
947 return scsi_convert_sense(dev->sense, dev->sense_len, buf, len, fixed); in scsi_device_get_sense()
950 void scsi_req_build_sense(SCSIRequest *req, SCSISense sense) in scsi_req_build_sense() argument
952 trace_scsi_req_build_sense(req->dev->id, req->lun, req->tag, in scsi_req_build_sense()
953 sense.key, sense.asc, sense.ascq); in scsi_req_build_sense()
954 req->sense_len = scsi_build_sense(req->sense, sense); in scsi_req_build_sense()
959 assert(!req->enqueued); in scsi_req_enqueue_internal()
961 if (req->bus->info->get_sg_list) { in scsi_req_enqueue_internal()
962 req->sg = req->bus->info->get_sg_list(req); in scsi_req_enqueue_internal()
964 req->sg = NULL; in scsi_req_enqueue_internal()
966 req->enqueued = true; in scsi_req_enqueue_internal()
967 QTAILQ_INSERT_TAIL(&req->dev->requests, req, next); in scsi_req_enqueue_internal()
974 assert(!req->retry); in scsi_req_enqueue()
977 rc = req->ops->send_command(req, req->cmd.buf); in scsi_req_enqueue()
984 trace_scsi_req_dequeue(req->dev->id, req->lun, req->tag); in scsi_req_dequeue()
985 req->retry = false; in scsi_req_dequeue()
986 if (req->enqueued) { in scsi_req_dequeue()
987 QTAILQ_REMOVE(&req->dev->requests, req, next); in scsi_req_dequeue()
988 req->enqueued = false; in scsi_req_dequeue()
995 /* MMC-6, paragraph 6.7. */ in scsi_get_performance_length()
999 /* Each descriptor is as in Table 295 - Nominal performance. */ in scsi_get_performance_length()
1002 /* Each descriptor is as in Table 296 - Exceptions. */ in scsi_get_performance_length()
1026 xfer_unit = dev->blocksize; in ata_passthrough_xfer_unit()
1045 case 3: /* USB-specific. */ in ata_passthrough_12_xfer()
1069 case 3: /* USB-specific. */ in ata_passthrough_16_xfer()
1088 cmd->xfer = scsi_cdb_xfer(buf); in scsi_req_xfer()
1115 cmd->xfer = 0; in scsi_req_xfer()
1121 cmd->xfer = 0; in scsi_req_xfer()
1123 cmd->xfer = 1; in scsi_req_xfer()
1125 cmd->xfer *= dev->blocksize; in scsi_req_xfer()
1131 cmd->xfer = buf[1] & 1 ? 0 : dev->blocksize; in scsi_req_xfer()
1134 cmd->xfer = 8; in scsi_req_xfer()
1137 cmd->xfer = 6; in scsi_req_xfer()
1141 if (dev->type == TYPE_ROM) { in scsi_req_xfer()
1142 cmd->xfer = buf[10] | (buf[9] << 8); in scsi_req_xfer()
1144 cmd->xfer = buf[9] | (buf[8] << 8); in scsi_req_xfer()
1149 if (cmd->xfer == 0) { in scsi_req_xfer()
1150 cmd->xfer = 256; in scsi_req_xfer()
1159 cmd->xfer *= dev->blocksize; in scsi_req_xfer()
1164 if (cmd->xfer == 0) { in scsi_req_xfer()
1165 cmd->xfer = 256; in scsi_req_xfer()
1171 cmd->xfer *= dev->blocksize; in scsi_req_xfer()
1174 /* MMC mandates the parameter list to be 12-bytes long. Parameters in scsi_req_xfer()
1176 if (dev->type == TYPE_ROM && (buf[1] & 16)) { in scsi_req_xfer()
1177 cmd->xfer = 12; in scsi_req_xfer()
1179 cmd->xfer = (buf[1] & 16) == 0 ? 0 : (buf[1] & 32 ? 8 : 4); in scsi_req_xfer()
1185 cmd->xfer = buf[4] | (buf[3] << 8); in scsi_req_xfer()
1191 cmd->xfer = buf[8] | (buf[7] << 8) | (buf[6] << 16); in scsi_req_xfer()
1194 cmd->xfer = ldl_be_p(&buf[5]) & 0xffffffffULL; in scsi_req_xfer()
1197 if (dev->type == TYPE_ROM) { in scsi_req_xfer()
1199 cmd->xfer = scsi_get_performance_length(buf[9] | (buf[8] << 8), in scsi_req_xfer()
1208 if (dev->type == TYPE_ROM) { in scsi_req_xfer()
1210 cmd->xfer = buf[9] | (buf[8] << 8); in scsi_req_xfer()
1214 if (dev->type == TYPE_ROM) { in scsi_req_xfer()
1216 cmd->xfer = 0; in scsi_req_xfer()
1218 cmd->xfer = ata_passthrough_12_xfer(dev, buf); in scsi_req_xfer()
1222 cmd->xfer = ata_passthrough_16_xfer(dev, buf); in scsi_req_xfer()
1234 cmd->xfer = 0; in scsi_req_stream_xfer()
1240 cmd->xfer = buf[4] | (buf[3] << 8) | (buf[2] << 16); in scsi_req_stream_xfer()
1242 cmd->xfer *= dev->blocksize; in scsi_req_stream_xfer()
1249 cmd->xfer = buf[14] | (buf[13] << 8) | (buf[12] << 16); in scsi_req_stream_xfer()
1251 cmd->xfer *= dev->blocksize; in scsi_req_stream_xfer()
1256 cmd->xfer = 0; in scsi_req_stream_xfer()
1259 cmd->xfer = buf[13] | (buf[12] << 8); in scsi_req_stream_xfer()
1265 cmd->xfer = 20; in scsi_req_stream_xfer()
1268 cmd->xfer = 32; in scsi_req_stream_xfer()
1271 cmd->xfer = buf[8] | (buf[7] << 8); in scsi_req_stream_xfer()
1274 return -1; in scsi_req_stream_xfer()
1279 cmd->xfer = buf[4] | (buf[3] << 8); in scsi_req_stream_xfer()
1297 cmd->xfer = 0; in scsi_req_medium_changer_xfer()
1300 cmd->xfer = buf[9] | (buf[8] << 8) | (buf[7] << 16); in scsi_req_medium_changer_xfer()
1315 cmd->xfer = 0; in scsi_req_scanner_length()
1318 cmd->xfer = buf[4]; in scsi_req_scanner_length()
1324 cmd->xfer = buf[8] | (buf[7] << 8) | (buf[6] << 16); in scsi_req_scanner_length()
1336 if (!cmd->xfer) { in scsi_cmd_xfer_mode()
1337 cmd->mode = SCSI_XFER_NONE; in scsi_cmd_xfer_mode()
1340 switch (cmd->buf[0]) { in scsi_cmd_xfer_mode()
1381 /* SCAN conflicts with START_STOP. START_STOP has cmd->xfer set to 0 for in scsi_cmd_xfer_mode()
1382 * non-scanner devices, so we only get here for SCAN and not for START_STOP. in scsi_cmd_xfer_mode()
1384 cmd->mode = SCSI_XFER_TO_DEV; in scsi_cmd_xfer_mode()
1389 cmd->mode = (cmd->buf[2] & 0x8) ? in scsi_cmd_xfer_mode()
1393 cmd->mode = SCSI_XFER_FROM_DEV; in scsi_cmd_xfer_mode()
1404 cmd->lba = -1; in scsi_req_parse_cdb()
1407 return -1; in scsi_req_parse_cdb()
1410 cmd->len = len; in scsi_req_parse_cdb()
1411 switch (dev->type) { in scsi_req_parse_cdb()
1429 memcpy(cmd->buf, buf, cmd->len); in scsi_req_parse_cdb()
1431 cmd->lba = scsi_cmd_lba(cmd); in scsi_req_parse_cdb()
1435 void scsi_device_report_change(SCSIDevice *dev, SCSISense sense) in scsi_device_report_change() argument
1437 SCSIBus *bus = DO_UPCAST(SCSIBus, qbus, dev->qdev.parent_bus); in scsi_device_report_change()
1439 scsi_device_set_ua(dev, sense); in scsi_device_report_change()
1440 if (bus->info->change) { in scsi_device_report_change()
1441 bus->info->change(bus, dev, sense); in scsi_device_report_change()
1447 assert(req->refcount > 0); in scsi_req_ref()
1448 req->refcount++; in scsi_req_ref()
1454 assert(req->refcount > 0); in scsi_req_unref()
1455 if (--req->refcount == 0) { in scsi_req_unref()
1456 BusState *qbus = req->dev->qdev.parent_bus; in scsi_req_unref()
1459 if (bus->info->free_request && req->hba_private) { in scsi_req_unref()
1460 bus->info->free_request(bus, req->hba_private); in scsi_req_unref()
1462 if (req->ops->free_req) { in scsi_req_unref()
1463 req->ops->free_req(req); in scsi_req_unref()
1465 object_unref(OBJECT(req->dev)); in scsi_req_unref()
1466 object_unref(OBJECT(qbus->parent)); in scsi_req_unref()
1475 if (req->io_canceled) { in scsi_req_continue()
1476 trace_scsi_req_continue_canceled(req->dev->id, req->lun, req->tag); in scsi_req_continue()
1479 trace_scsi_req_continue(req->dev->id, req->lun, req->tag); in scsi_req_continue()
1480 if (req->cmd.mode == SCSI_XFER_TO_DEV) { in scsi_req_continue()
1481 req->ops->write_data(req); in scsi_req_continue()
1483 req->ops->read_data(req); in scsi_req_continue()
1493 if (req->io_canceled) { in scsi_req_data()
1494 trace_scsi_req_data_canceled(req->dev->id, req->lun, req->tag, len); in scsi_req_data()
1497 trace_scsi_req_data(req->dev->id, req->lun, req->tag, len); in scsi_req_data()
1498 assert(req->cmd.mode != SCSI_XFER_NONE); in scsi_req_data()
1499 if (!req->sg) { in scsi_req_data()
1500 req->residual -= len; in scsi_req_data()
1501 req->bus->info->transfer_data(req, len); in scsi_req_data()
1508 assert(!req->dma_started); in scsi_req_data()
1509 req->dma_started = true; in scsi_req_data()
1512 if (req->cmd.mode == SCSI_XFER_FROM_DEV) { in scsi_req_data()
1513 dma_buf_read(buf, len, &req->residual, req->sg, in scsi_req_data()
1516 dma_buf_write(buf, len, &req->residual, req->sg, in scsi_req_data()
1528 req->dev->qdev.parent_bus->name, in scsi_req_print()
1529 req->dev->id, in scsi_req_print()
1530 scsi_command_name(req->cmd.buf[0])); in scsi_req_print()
1531 for (i = 1; i < req->cmd.len; i++) { in scsi_req_print()
1532 fprintf(fp, " 0x%02x", req->cmd.buf[i]); in scsi_req_print()
1534 switch (req->cmd.mode) { in scsi_req_print()
1536 fprintf(fp, " - none\n"); in scsi_req_print()
1539 fprintf(fp, " - from-dev len=%zd\n", req->cmd.xfer); in scsi_req_print()
1542 fprintf(fp, " - to-dev len=%zd\n", req->cmd.xfer); in scsi_req_print()
1545 fprintf(fp, " - Oops\n"); in scsi_req_print()
1552 SCSISense sense; in scsi_req_complete_failed() local
1555 assert(req->status == -1 && req->host_status == -1); in scsi_req_complete_failed()
1556 assert(req->ops != &reqops_unit_attention); in scsi_req_complete_failed()
1558 if (!req->bus->info->fail) { in scsi_req_complete_failed()
1559 status = scsi_sense_from_host_status(req->host_status, &sense); in scsi_req_complete_failed()
1561 scsi_req_build_sense(req, sense); in scsi_req_complete_failed()
1567 req->host_status = host_status; in scsi_req_complete_failed()
1570 req->bus->info->fail(req); in scsi_req_complete_failed()
1573 notifier_list_notify(&req->cancel_notifiers, req); in scsi_req_complete_failed()
1579 assert(req->status == -1 && req->host_status == -1); in scsi_req_complete()
1580 req->status = status; in scsi_req_complete()
1581 req->host_status = SCSI_HOST_OK; in scsi_req_complete()
1583 assert(req->sense_len <= sizeof(req->sense)); in scsi_req_complete()
1585 req->sense_len = 0; in scsi_req_complete()
1588 if (req->sense_len) { in scsi_req_complete()
1589 memcpy(req->dev->sense, req->sense, req->sense_len); in scsi_req_complete()
1590 req->dev->sense_len = req->sense_len; in scsi_req_complete()
1591 req->dev->sense_is_ua = (req->ops == &reqops_unit_attention); in scsi_req_complete()
1593 req->dev->sense_len = 0; in scsi_req_complete()
1594 req->dev->sense_is_ua = false; in scsi_req_complete()
1599 req->bus->info->complete(req, req->residual); in scsi_req_complete()
1602 notifier_list_notify(&req->cancel_notifiers, req); in scsi_req_complete()
1609 assert(req->io_canceled); in scsi_req_cancel_complete()
1610 if (req->bus->info->cancel) { in scsi_req_cancel_complete()
1611 req->bus->info->cancel(req); in scsi_req_cancel_complete()
1613 notifier_list_notify(&req->cancel_notifiers, req); in scsi_req_cancel_complete()
1623 trace_scsi_req_cancel(req->dev->id, req->lun, req->tag); in scsi_req_cancel_async()
1625 notifier_list_add(&req->cancel_notifiers, notifier); in scsi_req_cancel_async()
1627 if (req->io_canceled) { in scsi_req_cancel_async()
1632 assert(req->aiocb); in scsi_req_cancel_async()
1638 req->io_canceled = true; in scsi_req_cancel_async()
1639 if (req->aiocb) { in scsi_req_cancel_async()
1640 blk_aio_cancel_async(req->aiocb); in scsi_req_cancel_async()
1648 trace_scsi_req_cancel(req->dev->id, req->lun, req->tag); in scsi_req_cancel()
1649 if (!req->enqueued) { in scsi_req_cancel()
1652 assert(!req->io_canceled); in scsi_req_cancel()
1656 req->io_canceled = true; in scsi_req_cancel()
1657 if (req->aiocb) { in scsi_req_cancel()
1658 blk_aio_cancel(req->aiocb); in scsi_req_cancel()
1664 static int scsi_ua_precedence(SCSISense sense) in scsi_ua_precedence() argument
1666 if (sense.key != UNIT_ATTENTION) { in scsi_ua_precedence()
1669 if (sense.asc == 0x29 && sense.ascq == 0x04) { in scsi_ua_precedence()
1672 } else if (sense.asc == 0x3F && sense.ascq == 0x01) { in scsi_ua_precedence()
1675 } else if (sense.asc == 0x29 && (sense.ascq == 0x05 || sense.ascq == 0x06)) { in scsi_ua_precedence()
1678 } else if (sense.asc == 0x29 && sense.ascq <= 0x07) { in scsi_ua_precedence()
1685 return sense.ascq; in scsi_ua_precedence()
1686 } else if (sense.asc == 0x2F && sense.ascq == 0x01) { in scsi_ua_precedence()
1690 return (sense.asc << 8) | sense.ascq; in scsi_ua_precedence()
1693 void scsi_bus_set_ua(SCSIBus *bus, SCSISense sense) in scsi_bus_set_ua() argument
1696 if (sense.key != UNIT_ATTENTION) { in scsi_bus_set_ua()
1701 * Override a pre-existing unit attention condition, except for a more in scsi_bus_set_ua()
1704 prec1 = scsi_ua_precedence(bus->unit_attention); in scsi_bus_set_ua()
1705 prec2 = scsi_ua_precedence(sense); in scsi_bus_set_ua()
1707 bus->unit_attention = sense; in scsi_bus_set_ua()
1711 void scsi_device_set_ua(SCSIDevice *sdev, SCSISense sense) in scsi_device_set_ua() argument
1714 if (sense.key != UNIT_ATTENTION) { in scsi_device_set_ua()
1717 trace_scsi_device_set_ua(sdev->id, sdev->lun, sense.key, in scsi_device_set_ua()
1718 sense.asc, sense.ascq); in scsi_device_set_ua()
1721 * Override a pre-existing unit attention condition, except for a more in scsi_device_set_ua()
1724 prec1 = scsi_ua_precedence(sdev->unit_attention); in scsi_device_set_ua()
1725 prec2 = scsi_ua_precedence(sense); in scsi_device_set_ua()
1727 sdev->unit_attention = sense; in scsi_device_set_ua()
1739 void scsi_device_purge_requests(SCSIDevice *sdev, SCSISense sense) in scsi_device_purge_requests() argument
1748 blk_drain(sdev->conf.blk); in scsi_device_purge_requests()
1750 scsi_device_set_ua(sdev, sense); in scsi_device_purge_requests()
1755 SCSIBus *bus = DO_UPCAST(SCSIBus, qbus, sdev->qdev.parent_bus); in scsi_device_drained_begin()
1761 assert(bus->drain_count < INT_MAX); in scsi_device_drained_begin()
1767 if (bus->drain_count++ == 0) { in scsi_device_drained_begin()
1769 if (bus->info->drained_begin) { in scsi_device_drained_begin()
1770 bus->info->drained_begin(bus); in scsi_device_drained_begin()
1777 SCSIBus *bus = DO_UPCAST(SCSIBus, qbus, sdev->qdev.parent_bus); in scsi_device_drained_end()
1783 assert(bus->drain_count > 0); in scsi_device_drained_end()
1785 if (bus->drain_count-- == 1) { in scsi_device_drained_end()
1787 if (bus->info->drained_end) { in scsi_device_drained_end()
1788 bus->info->drained_end(bus); in scsi_device_drained_end()
1796 DeviceState *hba = dev->parent_bus->parent; in scsibus_get_dev_path()
1802 path = g_strdup_printf("%s/%d:%d:%d", id, d->channel, d->id, d->lun); in scsibus_get_dev_path()
1804 path = g_strdup_printf("%d:%d:%d", d->channel, d->id, d->lun); in scsibus_get_dev_path()
1813 return g_strdup_printf("channel@%x/%s@%x,%x", d->channel, in scsibus_get_fw_dev_path()
1814 qdev_fw_name(dev), d->id, d->lun); in scsibus_get_fw_dev_path()
1823 assert(!req->io_canceled); in put_scsi_req()
1824 assert(req->status == -1 && req->host_status == -1); in put_scsi_req()
1825 assert(req->enqueued); in put_scsi_req()
1827 qemu_put_sbyte(f, req->retry ? 1 : 2); in put_scsi_req()
1828 qemu_put_buffer(f, req->cmd.buf, sizeof(req->cmd.buf)); in put_scsi_req()
1829 qemu_put_be32s(f, &req->tag); in put_scsi_req()
1830 qemu_put_be32s(f, &req->lun); in put_scsi_req()
1831 if (req->bus->info->save_request) { in put_scsi_req()
1832 req->bus->info->save_request(f, req); in put_scsi_req()
1834 if (req->ops->save_request) { in put_scsi_req()
1835 req->ops->save_request(f, req); in put_scsi_req()
1853 SCSIBus *bus = DO_UPCAST(SCSIBus, qbus, s->qdev.parent_bus); in get_scsi_requests()
1866 * A too-short CDB would have been rejected by scsi_req_new, so just use in get_scsi_requests()
1870 req->retry = (sbyte == 1); in get_scsi_requests()
1871 if (bus->info->load_request) { in get_scsi_requests()
1872 req->hba_private = bus->info->load_request(f, req); in get_scsi_requests()
1874 if (req->ops->load_request) { in get_scsi_requests()
1875 req->ops->load_request(f, req); in get_scsi_requests()
1893 .name = "scsi-requests",
1902 return s->sense_len > SCSI_SENSE_BUF_SIZE_OLD; in scsi_sense_state_needed()
1906 .name = "SCSIDevice/sense",
1911 VMSTATE_UINT8_SUB_ARRAY(sense, SCSIDevice,
1913 SCSI_SENSE_BUF_SIZE - SCSI_SENSE_BUF_SIZE_OLD),
1927 VMSTATE_UINT8_SUB_ARRAY(sense, SCSIDevice, 0, SCSI_SENSE_BUF_SIZE_OLD),
1948 DEFINE_PROP_UINT32("scsi-id", SCSIDevice, id, -1),
1949 DEFINE_PROP_UINT32("lun", SCSIDevice, lun, -1),
1956 set_bit(DEVICE_CATEGORY_STORAGE, k->categories); in scsi_device_class_init()
1957 k->bus_type = TYPE_SCSI_BUS; in scsi_device_class_init()
1958 k->realize = scsi_qdev_realize; in scsi_device_class_init()
1959 k->unrealize = scsi_qdev_unrealize; in scsi_device_class_init()
1968 device_add_bootindex_property(obj, &s->conf.bootindex, in scsi_dev_instance_init()
1970 &s->qdev); in scsi_dev_instance_init()
1988 k->get_dev_path = scsibus_get_dev_path; in scsi_bus_class_init()
1989 k->get_fw_dev_path = scsibus_get_fw_dev_path; in scsi_bus_class_init()
1990 k->check_address = scsi_bus_check_address; in scsi_bus_class_init()
1991 hc->unplug = qdev_simple_device_unplug_cb; in scsi_bus_class_init()