Howdy. Attached is a patch that includes handling the REPORT_LUNS opcode which is used by SeaBIOS 1.11.x .
Comments? Ok? +--+ Carlos
Index: vioscsi.c =================================================================== RCS file: /home/los/cvs/src/usr.sbin/vmd/vioscsi.c,v retrieving revision 1.2 diff -u -p -a -u -r1.2 vioscsi.c --- vioscsi.c 15 Jan 2018 04:26:58 -0000 1.2 +++ vioscsi.c 16 Jan 2018 04:48:03 -0000 @@ -772,6 +772,105 @@ read_capacity_16_out: } static int +vioscsi_handle_report_luns(struct vioscsi_dev *dev, + struct virtio_scsi_req_hdr *req, struct virtio_vq_acct *acct) +{ + int ret = 0; + struct virtio_scsi_res_hdr resp; + uint32_t rpl_length; + struct scsi_report_luns *rpl; + struct vioscsi_report_luns_data *reply_rpl; + + memset(&resp, 0, sizeof(resp)); + rpl = (struct scsi_report_luns *)(req->cdb); + rpl_length = _4btol(rpl->length); + + log_debug("%s: REPORT_LUNS Report 0x%x Length %d", __func__, + rpl->selectreport, rpl_length); + + if (rpl_length < RPL_MIN_SIZE) { + log_debug("%s: RPL_Length %d < %d (RPL_MIN_SIZE)", __func__, + rpl_length, RPL_MIN_SIZE); + + vioscsi_prepare_resp(&resp, + VIRTIO_SCSI_S_OK, SCSI_CHECK, SKEY_ILLEGAL_REQUEST, + SENSE_ILLEGAL_CDB_FIELD, SENSE_DEFAULT_ASCQ); + + /* Move index for response */ + acct->resp_desc = vioscsi_next_ring_desc(acct->desc, + acct->req_desc, &(acct->resp_idx)); + + if (write_mem(acct->resp_desc->addr, &resp, + acct->resp_desc->len)) { + log_warnx("%s: unable to set ERR " + "status data @ 0x%llx", __func__, + acct->resp_desc->addr); + } else { + ret = 1; + dev->cfg.isr_status = 1; + /* Move ring indexes */ + vioscsi_next_ring_item(dev, acct->avail, acct->used, + acct->req_desc, acct->req_idx); + } + goto rpl_out; + + } + + reply_rpl = calloc(1, sizeof(*reply_rpl)); + + if (reply_rpl == NULL) { + log_warnx("%s: cannot alloc reply_rpl", __func__); + goto rpl_out; + } + + _lto4b(RPL_SINGLE_LUN, reply_rpl->length); + memcpy(reply_rpl->lun, req->lun, RPL_SINGLE_LUN); + + vioscsi_prepare_resp(&resp, + VIRTIO_SCSI_S_OK, SCSI_OK, 0, 0, 0); + + /* Move index for response */ + acct->resp_desc = vioscsi_next_ring_desc(acct->desc, acct->req_desc, + &(acct->resp_idx)); + + dprintf("%s: writing resp to 0x%llx size %d at local " + "idx %d req_idx %d global_idx %d", __func__, acct->resp_desc->addr, + acct->resp_desc->len, acct->resp_idx, acct->req_idx, acct->idx); + + if (write_mem(acct->resp_desc->addr, &resp, acct->resp_desc->len)) { + log_warnx("%s: unable to write OK resp status data @ 0x%llx", + __func__, acct->resp_desc->addr); + goto free_rpl; + } + + /* Move index for reply_rpl */ + acct->resp_desc = vioscsi_next_ring_desc(acct->desc, acct->resp_desc, + &(acct->resp_idx)); + + dprintf("%s: writing reply_rpl to 0x%llx size %d at " + "local idx %d req_idx %d global_idx %d", + __func__, acct->resp_desc->addr, acct->resp_desc->len, + acct->resp_idx, acct->req_idx, acct->idx); + + if (write_mem(acct->resp_desc->addr, reply_rpl, acct->resp_desc->len)) { + log_warnx("%s: unable to write reply_rpl" + " response to gpa @ 0x%llx", + __func__, acct->resp_desc->addr); + } else { + ret = 1; + dev->cfg.isr_status = 1; + /* Move ring indexes */ + vioscsi_next_ring_item(dev, acct->avail, acct->used, + acct->req_desc, acct->req_idx); + } + +free_rpl: + free(reply_rpl); +rpl_out: + return (ret); +} + +static int vioscsi_handle_read_6(struct vioscsi_dev *dev, struct virtio_scsi_req_hdr *req, struct virtio_vq_acct *acct) { @@ -2213,6 +2312,15 @@ vioscsi_notifyq(struct vioscsi_dev *dev) break; case MECHANISM_STATUS: ret = vioscsi_handle_mechanism_status(dev, &req, &acct); + if (ret) { + if (write_mem(q_gpa, vr, vr_sz)) { + log_warnx("%s: error writing vioring", + __func__); + } + } + break; + case REPORT_LUNS: + ret = vioscsi_handle_report_luns(dev, &req, &acct); if (ret) { if (write_mem(q_gpa, vr, vr_sz)) { log_warnx("%s: error writing vioring", Index: vioscsi.h =================================================================== RCS file: /home/los/cvs/src/usr.sbin/vmd/vioscsi.h,v retrieving revision 1.1 diff -u -p -a -u -r1.1 vioscsi.h --- vioscsi.h 3 Jan 2018 05:39:56 -0000 1.1 +++ vioscsi.h 16 Jan 2018 04:23:26 -0000 @@ -59,6 +59,8 @@ #define G_CONFIG_REPLY_SIZE 56 #define G_CONFIG_REPLY_SIZE_HEX 0x0034 +#define RPL_MIN_SIZE 16 + /* Opcodes not defined in scsi */ #define GET_EVENT_STATUS_NOTIFICATION 0x4a #define GET_CONFIGURATION 0x46 @@ -228,4 +230,15 @@ struct scsi_config_random_read_descripto u_int8_t blocking_type[2]; #define CONFIG_RANDOM_READ_BLOCKING_TYPE 0x0010 u_int8_t unused[2]; +}; + +/* + * Variant of scsi_report_luns_data in scsi_all.h + * but with only one lun in the lun list + */ +struct vioscsi_report_luns_data { + u_int8_t length[4]; + u_int8_t reserved[4]; +#define RPL_SINGLE_LUN 8 + u_int8_t lun[RPL_SINGLE_LUN]; };