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];
};