bdev-virtio: add test unit ready and start/stop to scan sequence
Tested with bdevio, hardcoded TUR response to test the start/stop unit code Change-Id: I5038e6bcce9fcd423f1b93c8bb8b466ee3817654 Signed-off-by: Paul Luse <paul.e.luse@intel.com> Reviewed-on: https://review.gerrithub.io/387183 Tested-by: SPDK Automated Test System <sys_sgsw@intel.com> Reviewed-by: Dariusz Stojaczyk <dariuszx.stojaczyk@intel.com> Reviewed-by: Daniel Verkamp <daniel.verkamp@intel.com> Reviewed-by: Jim Harris <james.r.harris@intel.com>
This commit is contained in:
parent
e0ba4da0b1
commit
04f528938d
@ -232,6 +232,8 @@ enum spdk_sbc_opcode {
|
||||
SPDK_SBC_VL_XPWRITE_32 = 0x0006,
|
||||
};
|
||||
|
||||
#define SPDK_SBC_START_STOP_UNIT_START_BIT (1 << 0)
|
||||
|
||||
enum spdk_mmc_opcode {
|
||||
/* MMC6 */
|
||||
SPDK_MMC_READ_DISC_STRUCTURE = 0xad,
|
||||
|
@ -723,18 +723,97 @@ send_read_cap_16(struct virtio_scsi_scan_base *base, uint8_t target_id, struct v
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
send_test_unit_ready(struct virtio_scsi_scan_base *base, uint8_t target_id, struct virtio_req *vreq)
|
||||
{
|
||||
struct virtio_scsi_cmd_req *req = vreq->iov_req.iov_base;
|
||||
int rc;
|
||||
|
||||
memset(req, 0, sizeof(*req));
|
||||
req->lun[0] = 1;
|
||||
req->lun[1] = target_id;
|
||||
req->cdb[0] = SPDK_SPC_TEST_UNIT_READY;
|
||||
|
||||
rc = virtio_xmit_pkt(base->vq, vreq);
|
||||
if (rc != 0) {
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
send_start_stop_unit(struct virtio_scsi_scan_base *base, uint8_t target_id, struct virtio_req *vreq)
|
||||
{
|
||||
struct virtio_scsi_cmd_req *req = vreq->iov_req.iov_base;
|
||||
int rc;
|
||||
|
||||
memset(req, 0, sizeof(*req));
|
||||
req->lun[0] = 1;
|
||||
req->lun[1] = target_id;
|
||||
req->cdb[0] = SPDK_SBC_START_STOP_UNIT;
|
||||
req->cdb[4] = SPDK_SBC_START_STOP_UNIT_START_BIT;
|
||||
|
||||
rc = virtio_xmit_pkt(base->vq, vreq);
|
||||
if (rc != 0) {
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
process_scan_start_stop_unit(struct virtio_scsi_scan_base *base, struct virtio_req *vreq)
|
||||
{
|
||||
struct virtio_scsi_cmd_req *req = vreq->iov_req.iov_base;
|
||||
struct virtio_scsi_cmd_resp *resp = vreq->iov_resp.iov_base;
|
||||
uint8_t target_id = req->lun[1];
|
||||
int rc = 0;
|
||||
|
||||
if (resp->response == VIRTIO_SCSI_S_OK && resp->status == SPDK_SCSI_STATUS_GOOD) {
|
||||
send_inquiry_vpd(base, target_id, vreq, SPDK_SPC_VPD_SUPPORTED_VPD_PAGES);
|
||||
} else {
|
||||
rc = -1;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
process_scan_test_unit_ready(struct virtio_scsi_scan_base *base, struct virtio_req *vreq)
|
||||
{
|
||||
struct virtio_scsi_cmd_req *req = vreq->iov_req.iov_base;
|
||||
struct virtio_scsi_cmd_resp *resp = vreq->iov_resp.iov_base;
|
||||
uint8_t target_id = req->lun[1];
|
||||
int sk, asc, ascq;
|
||||
int rc = 0;
|
||||
|
||||
get_scsi_status(resp, &sk, &asc, &ascq);
|
||||
|
||||
/* check response, get VPD if spun up otherwise send SSU */
|
||||
if (resp->response == VIRTIO_SCSI_S_OK && resp->status == SPDK_SCSI_STATUS_GOOD) {
|
||||
send_inquiry_vpd(base, target_id, vreq, SPDK_SPC_VPD_SUPPORTED_VPD_PAGES);
|
||||
} else if (resp->response == VIRTIO_SCSI_S_OK &&
|
||||
resp->status == SPDK_SCSI_STATUS_CHECK_CONDITION &&
|
||||
sk == SPDK_SCSI_SENSE_UNIT_ATTENTION &&
|
||||
asc == SPDK_SCSI_ASC_LOGICAL_UNIT_NOT_READY) {
|
||||
send_start_stop_unit(base, target_id, vreq);
|
||||
} else {
|
||||
rc = -1;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
process_scan_inquiry_standard(struct virtio_scsi_scan_base *base, struct virtio_req *vreq)
|
||||
{
|
||||
struct virtio_scsi_cmd_req *req = vreq->iov_req.iov_base;
|
||||
struct virtio_scsi_cmd_resp *resp = vreq->iov_resp.iov_base;
|
||||
struct spdk_scsi_cdb_inquiry_data *inquiry_data = vreq->iov[0].iov_base;
|
||||
uint8_t target_id;
|
||||
uint8_t target_id = req->lun[1];
|
||||
|
||||
if (resp->response != VIRTIO_SCSI_S_OK || resp->status != SPDK_SCSI_STATUS_GOOD) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* check to make sure its a supported device */
|
||||
if (inquiry_data->peripheral_device_type != SPDK_SPC_PERIPHERAL_DEVICE_TYPE_DISK ||
|
||||
inquiry_data->peripheral_qualifier != SPDK_SPC_PERIPHERAL_QUALIFIER_CONNECTED) {
|
||||
SPDK_WARNLOG("Unsupported peripheral device type 0x%02x (qualifier 0x%02x)\n",
|
||||
@ -743,8 +822,7 @@ process_scan_inquiry_standard(struct virtio_scsi_scan_base *base, struct virtio_
|
||||
return -1;
|
||||
}
|
||||
|
||||
target_id = req->lun[1];
|
||||
send_inquiry_vpd(base, target_id, vreq, SPDK_SPC_VPD_SUPPORTED_VPD_PAGES);
|
||||
send_test_unit_ready(base, target_id, vreq);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -956,6 +1034,12 @@ process_scan_resp(struct virtio_scsi_scan_base *base, struct virtio_req *vreq)
|
||||
case SPDK_SPC_INQUIRY:
|
||||
rc = process_scan_inquiry(base, vreq);
|
||||
break;
|
||||
case SPDK_SPC_TEST_UNIT_READY:
|
||||
rc = process_scan_test_unit_ready(base, vreq);
|
||||
break;
|
||||
case SPDK_SBC_START_STOP_UNIT:
|
||||
rc = process_scan_start_stop_unit(base, vreq);
|
||||
break;
|
||||
case SPDK_SBC_READ_CAPACITY_10:
|
||||
rc = process_read_cap_10(base, vreq);
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user