Lines Matching +full:check +full:- +full:patch

17 #include "qemu/error-report.h"
20 #include "migration/qemu-file-types.h"
21 #include "hw/qdev-properties.h"
22 #include "hw/qdev-properties-system.h"
24 #include "system/block-backend.h"
33 #define MAX_UINT ((unsigned int)-1)
48 qemu_put_sbe32s(f, &r->buflen); in scsi_generic_save_request()
49 if (r->buflen && r->req.cmd.mode == SCSI_XFER_TO_DEV) { in scsi_generic_save_request()
50 assert(!r->req.sg); in scsi_generic_save_request()
51 qemu_put_buffer(f, r->buf, r->req.cmd.xfer); in scsi_generic_save_request()
59 qemu_get_sbe32s(f, &r->buflen); in scsi_generic_load_request()
60 if (r->buflen && r->req.cmd.mode == SCSI_XFER_TO_DEV) { in scsi_generic_load_request()
61 assert(!r->req.sg); in scsi_generic_load_request()
62 qemu_get_buffer(f, r->buf, r->req.cmd.xfer); in scsi_generic_load_request()
70 g_free(r->buf); in scsi_free_request()
78 sg_io_hdr_t *io_hdr = &r->io_header; in scsi_command_complete_noio()
80 assert(r->req.aiocb == NULL); in scsi_command_complete_noio()
82 if (r->req.io_canceled) { in scsi_command_complete_noio()
83 scsi_req_cancel_complete(&r->req); in scsi_command_complete_noio()
87 status = scsi_sense_from_errno(-ret, &sense); in scsi_command_complete_noio()
89 scsi_req_build_sense(&r->req, sense); in scsi_command_complete_noio()
91 } else if (io_hdr->host_status != SCSI_HOST_OK) { in scsi_command_complete_noio()
92 scsi_req_complete_failed(&r->req, io_hdr->host_status); in scsi_command_complete_noio()
94 } else if (io_hdr->driver_status & SG_ERR_DRIVER_TIMEOUT) { in scsi_command_complete_noio()
97 status = io_hdr->status; in scsi_command_complete_noio()
98 if (io_hdr->driver_status & SG_ERR_DRIVER_SENSE) { in scsi_command_complete_noio()
99 r->req.sense_len = io_hdr->sb_len_wr; in scsi_command_complete_noio()
102 trace_scsi_generic_command_complete_noio(r, r->req.tag, status); in scsi_command_complete_noio()
104 scsi_req_complete(&r->req, status); in scsi_command_complete_noio()
106 scsi_req_unref(&r->req); in scsi_command_complete_noio()
113 assert(r->req.aiocb != NULL); in scsi_command_complete()
114 r->req.aiocb = NULL; in scsi_command_complete()
123 SCSIDevice *s = r->req.dev; in execute_command()
125 r->io_header.interface_id = 'S'; in execute_command()
126 r->io_header.dxfer_direction = direction; in execute_command()
127 r->io_header.dxferp = r->buf; in execute_command()
128 r->io_header.dxfer_len = r->buflen; in execute_command()
129 r->io_header.cmdp = r->req.cmd.buf; in execute_command()
130 r->io_header.cmd_len = r->req.cmd.len; in execute_command()
131 r->io_header.mx_sb_len = sizeof(r->req.sense); in execute_command()
132 r->io_header.sbp = r->req.sense; in execute_command()
133 r->io_header.timeout = s->io_timeout * 1000; in execute_command()
134 r->io_header.usr_ptr = r; in execute_command()
135 r->io_header.flags |= SG_FLAG_DIRECT_IO; in execute_command()
137 trace_scsi_generic_aio_sgio_command(r->req.tag, r->req.cmd.buf[0], in execute_command()
138 r->io_header.timeout); in execute_command()
139 r->req.aiocb = blk_aio_ioctl(blk, SG_IO, &r->io_header, complete, r); in execute_command()
140 if (r->req.aiocb == NULL) { in execute_command()
141 return -EIO; in execute_command()
149 uint64_t max_transfer = blk_get_max_hw_transfer(s->conf.blk); in calculate_max_transfer()
150 uint32_t max_iov = blk_get_max_hw_iov(s->conf.blk); in calculate_max_transfer()
156 return max_transfer / s->blocksize; in calculate_max_transfer()
166 * Check if scsi_version is unset (-1) to avoid re-defining it in scsi_handle_inquiry_reply()
168 * scsi_version is initialized with -1 in scsi_generic_reset in scsi_handle_inquiry_reply()
174 * On SCSI-2 and older, first 3 bits of byte 2 is the in scsi_handle_inquiry_reply()
175 * ANSI-approved version, while on later versions the in scsi_handle_inquiry_reply()
176 * whole byte 2 contains the version. Check if we're dealing in scsi_handle_inquiry_reply()
180 if (s->scsi_version == -1 && !(r->req.cmd.buf[1] & 0x01)) { in scsi_handle_inquiry_reply()
181 s->scsi_version = r->buf[2] & 0x07; in scsi_handle_inquiry_reply()
182 if (s->scsi_version > 2) { in scsi_handle_inquiry_reply()
183 s->scsi_version = r->buf[2]; in scsi_handle_inquiry_reply()
187 if ((s->type == TYPE_DISK || s->type == TYPE_ZBC) && in scsi_handle_inquiry_reply()
188 (r->req.cmd.buf[1] & 0x01)) { in scsi_handle_inquiry_reply()
189 page = r->req.cmd.buf[2]; in scsi_handle_inquiry_reply()
190 if (page == 0xb0 && r->buflen >= 8) { in scsi_handle_inquiry_reply()
192 uint8_t buf_used = MIN(r->buflen, 16); in scsi_handle_inquiry_reply()
195 memcpy(buf, r->buf, buf_used); in scsi_handle_inquiry_reply()
198 memcpy(r->buf + 8, buf + 8, buf_used - 8); in scsi_handle_inquiry_reply()
200 } else if (s->needs_vpd_bl_emulation && page == 0x00 && r->buflen >= 4) { in scsi_handle_inquiry_reply()
211 * right place with an in-place insert. When the while loop in scsi_handle_inquiry_reply()
212 * begins the device response is at r[0] to r[page_idx - 1]. in scsi_handle_inquiry_reply()
214 page_idx = lduw_be_p(r->buf + 2) + 4; in scsi_handle_inquiry_reply()
215 page_idx = MIN(page_idx, r->buflen); in scsi_handle_inquiry_reply()
216 while (page_idx > 4 && r->buf[page_idx - 1] >= 0xb0) { in scsi_handle_inquiry_reply()
217 if (page_idx < r->buflen) { in scsi_handle_inquiry_reply()
218 r->buf[page_idx] = r->buf[page_idx - 1]; in scsi_handle_inquiry_reply()
220 page_idx--; in scsi_handle_inquiry_reply()
222 if (page_idx < r->buflen) { in scsi_handle_inquiry_reply()
223 r->buf[page_idx] = 0xb0; in scsi_handle_inquiry_reply()
225 stw_be_p(r->buf + 2, lduw_be_p(r->buf + 2) + 1); in scsi_handle_inquiry_reply()
227 if (len < r->buflen) { in scsi_handle_inquiry_reply()
244 memset(r->buf, 0, r->buflen); in scsi_generic_emulate_block_limits()
245 stb_p(buf, s->type); in scsi_generic_emulate_block_limits()
248 assert(len <= sizeof(buf) - 4); in scsi_generic_emulate_block_limits()
251 memcpy(r->buf, buf, MIN(r->buflen, len + 4)); in scsi_generic_emulate_block_limits()
253 r->io_header.sb_len_wr = 0; in scsi_generic_emulate_block_limits()
261 r->io_header.driver_status = 0; in scsi_generic_emulate_block_limits()
262 r->io_header.status = 0; in scsi_generic_emulate_block_limits()
264 return r->buflen; in scsi_generic_emulate_block_limits()
270 SCSIDevice *s = r->req.dev; in scsi_read_complete()
273 assert(r->req.aiocb != NULL); in scsi_read_complete()
274 r->req.aiocb = NULL; in scsi_read_complete()
276 if (ret || r->req.io_canceled) { in scsi_read_complete()
281 len = r->io_header.dxfer_len - r->io_header.resid; in scsi_read_complete()
282 trace_scsi_generic_read_complete(r->req.tag, len); in scsi_read_complete()
284 r->len = -1; in scsi_read_complete()
286 if (r->io_header.driver_status & SG_ERR_DRIVER_SENSE) { in scsi_read_complete()
288 scsi_parse_sense_buf(r->req.sense, r->io_header.sb_len_wr); in scsi_read_complete()
291 * Check if this is a VPD Block Limits request that in scsi_read_complete()
296 s->needs_vpd_bl_emulation && in scsi_read_complete()
297 r->req.cmd.buf[0] == INQUIRY && in scsi_read_complete()
298 (r->req.cmd.buf[1] & 0x01) && in scsi_read_complete()
299 r->req.cmd.buf[2] == 0xb0) { in scsi_read_complete()
312 if (r->io_header.host_status != SCSI_HOST_OK || in scsi_read_complete()
313 (r->io_header.driver_status & SG_ERR_DRIVER_TIMEOUT) || in scsi_read_complete()
314 r->io_header.status != GOOD || in scsi_read_complete()
321 if (r->req.cmd.buf[0] == READ_CAPACITY_10 && in scsi_read_complete()
322 (ldl_be_p(&r->buf[0]) != 0xffffffffU || s->max_lba == 0)) { in scsi_read_complete()
323 s->blocksize = ldl_be_p(&r->buf[4]); in scsi_read_complete()
324 s->max_lba = ldl_be_p(&r->buf[0]) & 0xffffffffULL; in scsi_read_complete()
325 } else if (r->req.cmd.buf[0] == SERVICE_ACTION_IN_16 && in scsi_read_complete()
326 (r->req.cmd.buf[1] & 31) == SAI_READ_CAPACITY_16) { in scsi_read_complete()
327 s->blocksize = ldl_be_p(&r->buf[8]); in scsi_read_complete()
328 s->max_lba = ldq_be_p(&r->buf[0]); in scsi_read_complete()
332 * Patch MODE SENSE device specific parameters if the BDS is opened in scsi_read_complete()
335 if ((s->type == TYPE_DISK || s->type == TYPE_TAPE || s->type == TYPE_ZBC) && in scsi_read_complete()
336 !blk_is_writable(s->conf.blk) && in scsi_read_complete()
337 (r->req.cmd.buf[0] == MODE_SENSE || in scsi_read_complete()
338 r->req.cmd.buf[0] == MODE_SENSE_10) && in scsi_read_complete()
339 (r->req.cmd.buf[1] & 0x8) == 0) { in scsi_read_complete()
340 if (r->req.cmd.buf[0] == MODE_SENSE) { in scsi_read_complete()
341 r->buf[2] |= 0x80; in scsi_read_complete()
343 r->buf[3] |= 0x80; in scsi_read_complete()
346 if (r->req.cmd.buf[0] == INQUIRY) { in scsi_read_complete()
351 scsi_req_data(&r->req, len); in scsi_read_complete()
352 scsi_req_unref(&r->req); in scsi_read_complete()
359 SCSIDevice *s = r->req.dev; in scsi_read_data()
362 trace_scsi_generic_read_data(req->tag); in scsi_read_data()
365 scsi_req_ref(&r->req); in scsi_read_data()
366 if (r->len == -1) { in scsi_read_data()
371 ret = execute_command(s->conf.blk, r, SG_DXFER_FROM_DEV, in scsi_read_data()
381 SCSIDevice *s = r->req.dev; in scsi_write_complete()
385 assert(r->req.aiocb != NULL); in scsi_write_complete()
386 r->req.aiocb = NULL; in scsi_write_complete()
388 if (ret || r->req.io_canceled) { in scsi_write_complete()
393 if (r->req.cmd.buf[0] == MODE_SELECT && r->req.cmd.buf[4] == 12 && in scsi_write_complete()
394 s->type == TYPE_TAPE) { in scsi_write_complete()
395 s->blocksize = (r->buf[9] << 16) | (r->buf[10] << 8) | r->buf[11]; in scsi_write_complete()
396 trace_scsi_generic_write_complete_blocksize(s->blocksize); in scsi_write_complete()
407 SCSIDevice *s = r->req.dev; in scsi_write_data()
410 trace_scsi_generic_write_data(req->tag); in scsi_write_data()
411 if (r->len == 0) { in scsi_write_data()
412 r->len = r->buflen; in scsi_write_data()
413 scsi_req_data(&r->req, r->len); in scsi_write_data()
418 scsi_req_ref(&r->req); in scsi_write_data()
419 ret = execute_command(s->conf.blk, r, SG_DXFER_TO_DEV, scsi_write_complete); in scsi_write_data()
430 return r->buf; in scsi_get_buf()
456 SCSIDevice *s = r->req.dev; in scsi_send_command()
460 scsi_generic_command_dump(cmd, r->req.cmd.len); in scsi_send_command()
463 if (r->req.cmd.xfer == 0) { in scsi_send_command()
464 g_free(r->buf); in scsi_send_command()
465 r->buflen = 0; in scsi_send_command()
466 r->buf = NULL; in scsi_send_command()
468 scsi_req_ref(&r->req); in scsi_send_command()
469 ret = execute_command(s->conf.blk, r, SG_DXFER_NONE, in scsi_send_command()
478 if (r->buflen != r->req.cmd.xfer) { in scsi_send_command()
479 g_free(r->buf); in scsi_send_command()
480 r->buf = g_malloc(r->req.cmd.xfer); in scsi_send_command()
481 r->buflen = r->req.cmd.xfer; in scsi_send_command()
484 memset(r->buf, 0, r->buflen); in scsi_send_command()
485 r->len = r->req.cmd.xfer; in scsi_send_command()
486 if (r->req.cmd.mode == SCSI_XFER_TO_DEV) { in scsi_send_command()
487 r->len = 0; in scsi_send_command()
488 return -r->req.cmd.xfer; in scsi_send_command()
490 return r->req.cmd.xfer; in scsi_send_command()
501 return -EINVAL; in read_naa_id()
510 return -EINVAL; in read_naa_id()
513 return -EINVAL; in read_naa_id()
518 c -= (c >= '0' && c <= '9' ? '0' : 'A' - 10); in read_naa_id()
524 return -EINVAL; in read_naa_id()
551 return -1; in scsi_SG_IO_FROM_DEV()
576 ret = scsi_SG_IO_FROM_DEV(s->conf.blk, cmd, sizeof(cmd), in scsi_generic_set_vpd_bl_emulation()
577 buf, sizeof(buf), s->io_timeout); in scsi_generic_set_vpd_bl_emulation()
584 s->needs_vpd_bl_emulation = false; in scsi_generic_set_vpd_bl_emulation()
591 s->needs_vpd_bl_emulation = false; in scsi_generic_set_vpd_bl_emulation()
595 s->needs_vpd_bl_emulation = true; in scsi_generic_set_vpd_bl_emulation()
612 ret = scsi_SG_IO_FROM_DEV(s->conf.blk, cmd, sizeof(cmd), in scsi_generic_read_device_identification()
613 buf, sizeof(buf), s->io_timeout); in scsi_generic_read_device_identification()
618 len = MIN((buf[2] << 8) | buf[3], sizeof(buf) - 4); in scsi_generic_read_device_identification()
630 s->wwn = wwn; in scsi_generic_read_device_identification()
635 s->port_wwn = wwn; in scsi_generic_read_device_identification()
646 if (s->type == TYPE_DISK || s->type == TYPE_ZBC) { in scsi_generic_read_device_inquiry()
649 s->needs_vpd_bl_emulation = false; in scsi_generic_read_device_inquiry()
666 return -1; in get_stream_blocksize()
676 s->scsi_version = s->default_scsi_version; in scsi_generic_reset()
686 if (!s->conf.blk) { in scsi_generic_realize()
691 if (blk_get_on_error(s->conf.blk, 0) != BLOCKDEV_ON_ERROR_ENOSPC && in scsi_generic_realize()
692 blk_get_on_error(s->conf.blk, 0) != BLOCKDEV_ON_ERROR_REPORT) { in scsi_generic_realize()
696 if (blk_get_on_error(s->conf.blk, 1) != BLOCKDEV_ON_ERROR_REPORT) { in scsi_generic_realize()
701 /* check we are using a driver managing SG_IO (version 3 and after */ in scsi_generic_realize()
702 rc = blk_ioctl(s->conf.blk, SG_GET_VERSION_NUM, &sg_version); in scsi_generic_realize()
704 error_setg_errno(errp, -rc, "cannot get SG_IO version number"); in scsi_generic_realize()
705 if (rc != -EPERM) { in scsi_generic_realize()
716 if (blk_ioctl(s->conf.blk, SG_GET_SCSI_ID, &scsiid)) { in scsi_generic_realize()
720 if (!blkconf_apply_backend_options(&s->conf, in scsi_generic_realize()
721 !blk_supports_write_perm(s->conf.blk), in scsi_generic_realize()
727 s->type = scsiid.scsi_type; in scsi_generic_realize()
728 trace_scsi_generic_realize_type(s->type); in scsi_generic_realize()
730 switch (s->type) { in scsi_generic_realize()
732 s->blocksize = get_stream_blocksize(s->conf.blk); in scsi_generic_realize()
733 if (s->blocksize == -1) { in scsi_generic_realize()
734 s->blocksize = 0; in scsi_generic_realize()
744 s->blocksize = 2048; in scsi_generic_realize()
747 s->blocksize = 512; in scsi_generic_realize()
751 trace_scsi_generic_realize_blocksize(s->blocksize); in scsi_generic_realize()
753 /* Only used by scsi-block, but initialize it nevertheless to be clean. */ in scsi_generic_realize()
754 s->default_scsi_version = -1; in scsi_generic_realize()
777 DEFINE_PROP_BOOL("share-rw", SCSIDevice, conf.share_rw, false),
794 sc->realize = scsi_generic_realize; in scsi_generic_class_initfn()
795 sc->alloc_req = scsi_new_request; in scsi_generic_class_initfn()
796 sc->parse_cdb = scsi_generic_parse_cdb; in scsi_generic_class_initfn()
797 dc->fw_name = "disk"; in scsi_generic_class_initfn()
798 dc->desc = "pass through generic scsi device (/dev/sg*)"; in scsi_generic_class_initfn()
801 dc->vmsd = &vmstate_scsi_device; in scsi_generic_class_initfn()
805 .name = "scsi-generic",