mirror of
https://github.com/qemu/qemu.git
synced 2025-08-09 10:25:06 +00:00
Merge remote-tracking branch 'remotes/bonzini/scsi-next' into staging
* remotes/bonzini/scsi-next: block/iscsi: fix segfault if writesame fails scsi-disk: Add support for port WWN and index descriptors in VPD page 83h block/iscsi: query for supported VPD pages block/iscsi: fix deadlock on scsi check condition scsi-bus: Fix transfer length for VERIFY with BYTCHK=11b scsi: report thin provisioning errors with werror=report scsi: Change scsi sense buf size to 252 Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
739aa555b8
141
block/iscsi.c
141
block/iscsi.c
@ -145,12 +145,13 @@ iscsi_co_generic_cb(struct iscsi_context *iscsi, int status,
|
|||||||
|
|
||||||
if (iTask->retries-- > 0 && status == SCSI_STATUS_CHECK_CONDITION
|
if (iTask->retries-- > 0 && status == SCSI_STATUS_CHECK_CONDITION
|
||||||
&& task->sense.key == SCSI_SENSE_UNIT_ATTENTION) {
|
&& task->sense.key == SCSI_SENSE_UNIT_ATTENTION) {
|
||||||
|
error_report("iSCSI CheckCondition: %s", iscsi_get_error(iscsi));
|
||||||
iTask->do_retry = 1;
|
iTask->do_retry = 1;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status != SCSI_STATUS_GOOD) {
|
if (status != SCSI_STATUS_GOOD) {
|
||||||
error_report("iSCSI: Failure. %s", iscsi_get_error(iscsi));
|
error_report("iSCSI Failure: %s", iscsi_get_error(iscsi));
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
@ -325,6 +326,7 @@ retry:
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (iTask.do_retry) {
|
if (iTask.do_retry) {
|
||||||
|
iTask.complete = 0;
|
||||||
goto retry;
|
goto retry;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -399,6 +401,7 @@ retry:
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (iTask.do_retry) {
|
if (iTask.do_retry) {
|
||||||
|
iTask.complete = 0;
|
||||||
goto retry;
|
goto retry;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -433,6 +436,7 @@ retry:
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (iTask.do_retry) {
|
if (iTask.do_retry) {
|
||||||
|
iTask.complete = 0;
|
||||||
goto retry;
|
goto retry;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -683,6 +687,7 @@ retry:
|
|||||||
scsi_free_scsi_task(iTask.task);
|
scsi_free_scsi_task(iTask.task);
|
||||||
iTask.task = NULL;
|
iTask.task = NULL;
|
||||||
}
|
}
|
||||||
|
iTask.complete = 0;
|
||||||
goto retry;
|
goto retry;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -767,6 +772,7 @@ retry:
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (iTask.do_retry) {
|
if (iTask.do_retry) {
|
||||||
|
iTask.complete = 0;
|
||||||
goto retry;
|
goto retry;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -830,24 +836,26 @@ retry:
|
|||||||
qemu_coroutine_yield();
|
qemu_coroutine_yield();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (iTask.status == SCSI_STATUS_CHECK_CONDITION &&
|
||||||
|
iTask.task->sense.key == SCSI_SENSE_ILLEGAL_REQUEST &&
|
||||||
|
iTask.task->sense.ascq == SCSI_SENSE_ASCQ_INVALID_OPERATION_CODE) {
|
||||||
|
/* WRITE SAME is not supported by the target */
|
||||||
|
iscsilun->has_write_same = false;
|
||||||
|
scsi_free_scsi_task(iTask.task);
|
||||||
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
|
||||||
if (iTask.task != NULL) {
|
if (iTask.task != NULL) {
|
||||||
scsi_free_scsi_task(iTask.task);
|
scsi_free_scsi_task(iTask.task);
|
||||||
iTask.task = NULL;
|
iTask.task = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (iTask.do_retry) {
|
if (iTask.do_retry) {
|
||||||
|
iTask.complete = 0;
|
||||||
goto retry;
|
goto retry;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (iTask.status != SCSI_STATUS_GOOD) {
|
if (iTask.status != SCSI_STATUS_GOOD) {
|
||||||
if (iTask.status == SCSI_STATUS_CHECK_CONDITION &&
|
|
||||||
iTask.task->sense.key == SCSI_SENSE_ILLEGAL_REQUEST &&
|
|
||||||
iTask.task->sense.ascq == SCSI_SENSE_ASCQ_INVALID_OPERATION_CODE) {
|
|
||||||
/* WRITE SAME is not supported by the target */
|
|
||||||
iscsilun->has_write_same = false;
|
|
||||||
return -ENOTSUP;
|
|
||||||
}
|
|
||||||
|
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1060,7 +1068,7 @@ static QemuOptsList runtime_opts = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static struct scsi_task *iscsi_do_inquiry(struct iscsi_context *iscsi, int lun,
|
static struct scsi_task *iscsi_do_inquiry(struct iscsi_context *iscsi, int lun,
|
||||||
int evpd, int pc, Error **errp)
|
int evpd, int pc, void **inq, Error **errp)
|
||||||
{
|
{
|
||||||
int full_size;
|
int full_size;
|
||||||
struct scsi_task *task = NULL;
|
struct scsi_task *task = NULL;
|
||||||
@ -1079,14 +1087,19 @@ static struct scsi_task *iscsi_do_inquiry(struct iscsi_context *iscsi, int lun,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*inq = scsi_datain_unmarshall(task);
|
||||||
|
if (*inq == NULL) {
|
||||||
|
error_setg(errp, "iSCSI: failed to unmarshall inquiry datain blob");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
return task;
|
return task;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
error_setg(errp, "iSCSI: Inquiry command failed : %s",
|
error_setg(errp, "iSCSI: Inquiry command failed : %s",
|
||||||
iscsi_get_error(iscsi));
|
iscsi_get_error(iscsi));
|
||||||
if (task) {
|
if (task != NULL) {
|
||||||
scsi_free_scsi_task(task);
|
scsi_free_scsi_task(task);
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -1107,11 +1120,12 @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags,
|
|||||||
struct iscsi_url *iscsi_url = NULL;
|
struct iscsi_url *iscsi_url = NULL;
|
||||||
struct scsi_task *task = NULL;
|
struct scsi_task *task = NULL;
|
||||||
struct scsi_inquiry_standard *inq = NULL;
|
struct scsi_inquiry_standard *inq = NULL;
|
||||||
|
struct scsi_inquiry_supported_pages *inq_vpd;
|
||||||
char *initiator_name = NULL;
|
char *initiator_name = NULL;
|
||||||
QemuOpts *opts;
|
QemuOpts *opts;
|
||||||
Error *local_err = NULL;
|
Error *local_err = NULL;
|
||||||
const char *filename;
|
const char *filename;
|
||||||
int ret;
|
int i, ret;
|
||||||
|
|
||||||
if ((BDRV_SECTOR_SIZE % 512) != 0) {
|
if ((BDRV_SECTOR_SIZE % 512) != 0) {
|
||||||
error_setg(errp, "iSCSI: Invalid BDRV_SECTOR_SIZE. "
|
error_setg(errp, "iSCSI: Invalid BDRV_SECTOR_SIZE. "
|
||||||
@ -1197,25 +1211,18 @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags,
|
|||||||
|
|
||||||
iscsilun->iscsi = iscsi;
|
iscsilun->iscsi = iscsi;
|
||||||
iscsilun->lun = iscsi_url->lun;
|
iscsilun->lun = iscsi_url->lun;
|
||||||
|
|
||||||
task = iscsi_inquiry_sync(iscsi, iscsilun->lun, 0, 0, 36);
|
|
||||||
|
|
||||||
if (task == NULL || task->status != SCSI_STATUS_GOOD) {
|
|
||||||
error_setg(errp, "iSCSI: failed to send inquiry command.");
|
|
||||||
ret = -EINVAL;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
inq = scsi_datain_unmarshall(task);
|
|
||||||
if (inq == NULL) {
|
|
||||||
error_setg(errp, "iSCSI: Failed to unmarshall inquiry data.");
|
|
||||||
ret = -EINVAL;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
iscsilun->type = inq->periperal_device_type;
|
|
||||||
iscsilun->has_write_same = true;
|
iscsilun->has_write_same = true;
|
||||||
|
|
||||||
|
task = iscsi_do_inquiry(iscsilun->iscsi, iscsilun->lun, 0, 0,
|
||||||
|
(void **) &inq, errp);
|
||||||
|
if (task == NULL) {
|
||||||
|
ret = -EINVAL;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
iscsilun->type = inq->periperal_device_type;
|
||||||
|
scsi_free_scsi_task(task);
|
||||||
|
task = NULL;
|
||||||
|
|
||||||
iscsi_readcapacity_sync(iscsilun, &local_err);
|
iscsi_readcapacity_sync(iscsilun, &local_err);
|
||||||
if (local_err != NULL) {
|
if (local_err != NULL) {
|
||||||
error_propagate(errp, local_err);
|
error_propagate(errp, local_err);
|
||||||
@ -1233,46 +1240,48 @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags,
|
|||||||
bs->sg = 1;
|
bs->sg = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (iscsilun->lbpme) {
|
task = iscsi_do_inquiry(iscsilun->iscsi, iscsilun->lun, 1,
|
||||||
|
SCSI_INQUIRY_PAGECODE_SUPPORTED_VPD_PAGES,
|
||||||
|
(void **) &inq_vpd, errp);
|
||||||
|
if (task == NULL) {
|
||||||
|
ret = -EINVAL;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
for (i = 0; i < inq_vpd->num_pages; i++) {
|
||||||
|
struct scsi_task *inq_task;
|
||||||
struct scsi_inquiry_logical_block_provisioning *inq_lbp;
|
struct scsi_inquiry_logical_block_provisioning *inq_lbp;
|
||||||
task = iscsi_do_inquiry(iscsilun->iscsi, iscsilun->lun, 1,
|
|
||||||
SCSI_INQUIRY_PAGECODE_LOGICAL_BLOCK_PROVISIONING,
|
|
||||||
errp);
|
|
||||||
if (task == NULL) {
|
|
||||||
ret = -EINVAL;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
inq_lbp = scsi_datain_unmarshall(task);
|
|
||||||
if (inq_lbp == NULL) {
|
|
||||||
error_setg(errp, "iSCSI: failed to unmarshall inquiry datain blob");
|
|
||||||
ret = -EINVAL;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
memcpy(&iscsilun->lbp, inq_lbp,
|
|
||||||
sizeof(struct scsi_inquiry_logical_block_provisioning));
|
|
||||||
scsi_free_scsi_task(task);
|
|
||||||
task = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (iscsilun->lbp.lbpu || iscsilun->lbp.lbpws) {
|
|
||||||
struct scsi_inquiry_block_limits *inq_bl;
|
struct scsi_inquiry_block_limits *inq_bl;
|
||||||
task = iscsi_do_inquiry(iscsilun->iscsi, iscsilun->lun, 1,
|
switch (inq_vpd->pages[i]) {
|
||||||
SCSI_INQUIRY_PAGECODE_BLOCK_LIMITS, errp);
|
case SCSI_INQUIRY_PAGECODE_LOGICAL_BLOCK_PROVISIONING:
|
||||||
if (task == NULL) {
|
inq_task = iscsi_do_inquiry(iscsilun->iscsi, iscsilun->lun, 1,
|
||||||
ret = -EINVAL;
|
SCSI_INQUIRY_PAGECODE_LOGICAL_BLOCK_PROVISIONING,
|
||||||
goto out;
|
(void **) &inq_lbp, errp);
|
||||||
|
if (inq_task == NULL) {
|
||||||
|
ret = -EINVAL;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
memcpy(&iscsilun->lbp, inq_lbp,
|
||||||
|
sizeof(struct scsi_inquiry_logical_block_provisioning));
|
||||||
|
scsi_free_scsi_task(inq_task);
|
||||||
|
break;
|
||||||
|
case SCSI_INQUIRY_PAGECODE_BLOCK_LIMITS:
|
||||||
|
inq_task = iscsi_do_inquiry(iscsilun->iscsi, iscsilun->lun, 1,
|
||||||
|
SCSI_INQUIRY_PAGECODE_BLOCK_LIMITS,
|
||||||
|
(void **) &inq_bl, errp);
|
||||||
|
if (inq_task == NULL) {
|
||||||
|
ret = -EINVAL;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
memcpy(&iscsilun->bl, inq_bl,
|
||||||
|
sizeof(struct scsi_inquiry_block_limits));
|
||||||
|
scsi_free_scsi_task(inq_task);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
inq_bl = scsi_datain_unmarshall(task);
|
|
||||||
if (inq_bl == NULL) {
|
|
||||||
error_setg(errp, "iSCSI: failed to unmarshall inquiry datain blob");
|
|
||||||
ret = -EINVAL;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
memcpy(&iscsilun->bl, inq_bl,
|
|
||||||
sizeof(struct scsi_inquiry_block_limits));
|
|
||||||
scsi_free_scsi_task(task);
|
|
||||||
task = NULL;
|
|
||||||
}
|
}
|
||||||
|
scsi_free_scsi_task(task);
|
||||||
|
task = NULL;
|
||||||
|
|
||||||
#if defined(LIBISCSI_FEATURE_NOP_COUNTER)
|
#if defined(LIBISCSI_FEATURE_NOP_COUNTER)
|
||||||
/* Set up a timer for sending out iSCSI NOPs */
|
/* Set up a timer for sending out iSCSI NOPs */
|
||||||
|
@ -909,7 +909,7 @@ static int scsi_req_length(SCSICommand *cmd, SCSIDevice *dev, uint8_t *buf)
|
|||||||
case VERIFY_16:
|
case VERIFY_16:
|
||||||
if ((buf[1] & 2) == 0) {
|
if ((buf[1] & 2) == 0) {
|
||||||
cmd->xfer = 0;
|
cmd->xfer = 0;
|
||||||
} else if ((buf[1] & 4) == 1) {
|
} else if ((buf[1] & 4) != 0) {
|
||||||
cmd->xfer = 1;
|
cmd->xfer = 1;
|
||||||
}
|
}
|
||||||
cmd->xfer *= dev->blocksize;
|
cmd->xfer *= dev->blocksize;
|
||||||
@ -1367,6 +1367,11 @@ const struct SCSISense sense_code_WRITE_PROTECTED = {
|
|||||||
.key = DATA_PROTECT, .asc = 0x27, .ascq = 0x00
|
.key = DATA_PROTECT, .asc = 0x27, .ascq = 0x00
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Data Protection, Space Allocation Failed Write Protect */
|
||||||
|
const struct SCSISense sense_code_SPACE_ALLOC_FAILED = {
|
||||||
|
.key = DATA_PROTECT, .asc = 0x27, .ascq = 0x07
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* scsi_build_sense
|
* scsi_build_sense
|
||||||
*
|
*
|
||||||
|
@ -75,6 +75,8 @@ struct SCSIDiskState
|
|||||||
bool media_event;
|
bool media_event;
|
||||||
bool eject_request;
|
bool eject_request;
|
||||||
uint64_t wwn;
|
uint64_t wwn;
|
||||||
|
uint64_t port_wwn;
|
||||||
|
uint16_t port_index;
|
||||||
uint64_t max_unmap_size;
|
uint64_t max_unmap_size;
|
||||||
QEMUBH *bh;
|
QEMUBH *bh;
|
||||||
char *version;
|
char *version;
|
||||||
@ -428,6 +430,9 @@ static int scsi_handle_rw_error(SCSIDiskReq *r, int error)
|
|||||||
case EINVAL:
|
case EINVAL:
|
||||||
scsi_check_condition(r, SENSE_CODE(INVALID_FIELD));
|
scsi_check_condition(r, SENSE_CODE(INVALID_FIELD));
|
||||||
break;
|
break;
|
||||||
|
case ENOSPC:
|
||||||
|
scsi_check_condition(r, SENSE_CODE(SPACE_ALLOC_FAILED));
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
scsi_check_condition(r, SENSE_CODE(IO_ERROR));
|
scsi_check_condition(r, SENSE_CODE(IO_ERROR));
|
||||||
break;
|
break;
|
||||||
@ -617,6 +622,24 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf)
|
|||||||
stq_be_p(&outbuf[buflen], s->wwn);
|
stq_be_p(&outbuf[buflen], s->wwn);
|
||||||
buflen += 8;
|
buflen += 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (s->port_wwn) {
|
||||||
|
outbuf[buflen++] = 0x61; // SAS / Binary
|
||||||
|
outbuf[buflen++] = 0x93; // PIV / Target port / NAA
|
||||||
|
outbuf[buflen++] = 0; // reserved
|
||||||
|
outbuf[buflen++] = 8;
|
||||||
|
stq_be_p(&outbuf[buflen], s->port_wwn);
|
||||||
|
buflen += 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (s->port_index) {
|
||||||
|
outbuf[buflen++] = 0x61; // SAS / Binary
|
||||||
|
outbuf[buflen++] = 0x94; // PIV / Target port / relative target port
|
||||||
|
outbuf[buflen++] = 0; // reserved
|
||||||
|
outbuf[buflen++] = 4;
|
||||||
|
stw_be_p(&outbuf[buflen + 2], s->port_index);
|
||||||
|
buflen += 4;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 0xb0: /* block limits */
|
case 0xb0: /* block limits */
|
||||||
@ -2536,6 +2559,8 @@ static Property scsi_hd_properties[] = {
|
|||||||
DEFINE_PROP_BIT("dpofua", SCSIDiskState, features,
|
DEFINE_PROP_BIT("dpofua", SCSIDiskState, features,
|
||||||
SCSI_DISK_F_DPOFUA, false),
|
SCSI_DISK_F_DPOFUA, false),
|
||||||
DEFINE_PROP_UINT64("wwn", SCSIDiskState, wwn, 0),
|
DEFINE_PROP_UINT64("wwn", SCSIDiskState, wwn, 0),
|
||||||
|
DEFINE_PROP_UINT64("port_wwn", SCSIDiskState, port_wwn, 0),
|
||||||
|
DEFINE_PROP_UINT16("port_index", SCSIDiskState, port_index, 0),
|
||||||
DEFINE_PROP_UINT64("max_unmap_size", SCSIDiskState, max_unmap_size,
|
DEFINE_PROP_UINT64("max_unmap_size", SCSIDiskState, max_unmap_size,
|
||||||
DEFAULT_MAX_UNMAP_SIZE),
|
DEFAULT_MAX_UNMAP_SIZE),
|
||||||
DEFINE_BLOCK_CHS_PROPERTIES(SCSIDiskState, qdev.conf),
|
DEFINE_BLOCK_CHS_PROPERTIES(SCSIDiskState, qdev.conf),
|
||||||
@ -2584,6 +2609,8 @@ static const TypeInfo scsi_hd_info = {
|
|||||||
static Property scsi_cd_properties[] = {
|
static Property scsi_cd_properties[] = {
|
||||||
DEFINE_SCSI_DISK_PROPERTIES(),
|
DEFINE_SCSI_DISK_PROPERTIES(),
|
||||||
DEFINE_PROP_UINT64("wwn", SCSIDiskState, wwn, 0),
|
DEFINE_PROP_UINT64("wwn", SCSIDiskState, wwn, 0),
|
||||||
|
DEFINE_PROP_UINT64("port_wwn", SCSIDiskState, port_wwn, 0),
|
||||||
|
DEFINE_PROP_UINT16("port_index", SCSIDiskState, port_index, 0),
|
||||||
DEFINE_PROP_END_OF_LIST(),
|
DEFINE_PROP_END_OF_LIST(),
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -2647,6 +2674,8 @@ static Property scsi_disk_properties[] = {
|
|||||||
DEFINE_PROP_BIT("dpofua", SCSIDiskState, features,
|
DEFINE_PROP_BIT("dpofua", SCSIDiskState, features,
|
||||||
SCSI_DISK_F_DPOFUA, false),
|
SCSI_DISK_F_DPOFUA, false),
|
||||||
DEFINE_PROP_UINT64("wwn", SCSIDiskState, wwn, 0),
|
DEFINE_PROP_UINT64("wwn", SCSIDiskState, wwn, 0),
|
||||||
|
DEFINE_PROP_UINT64("port_wwn", SCSIDiskState, port_wwn, 0),
|
||||||
|
DEFINE_PROP_UINT16("port_index", SCSIDiskState, port_index, 0),
|
||||||
DEFINE_PROP_UINT64("max_unmap_size", SCSIDiskState, max_unmap_size,
|
DEFINE_PROP_UINT64("max_unmap_size", SCSIDiskState, max_unmap_size,
|
||||||
DEFAULT_MAX_UNMAP_SIZE),
|
DEFAULT_MAX_UNMAP_SIZE),
|
||||||
DEFINE_PROP_END_OF_LIST(),
|
DEFINE_PROP_END_OF_LIST(),
|
||||||
|
@ -37,8 +37,6 @@ do { fprintf(stderr, "scsi-generic: " fmt , ## __VA_ARGS__); } while (0)
|
|||||||
#include <scsi/sg.h>
|
#include <scsi/sg.h>
|
||||||
#include "block/scsi.h"
|
#include "block/scsi.h"
|
||||||
|
|
||||||
#define SCSI_SENSE_BUF_SIZE 96
|
|
||||||
|
|
||||||
#define SG_ERR_DRIVER_TIMEOUT 0x06
|
#define SG_ERR_DRIVER_TIMEOUT 0x06
|
||||||
#define SG_ERR_DRIVER_SENSE 0x08
|
#define SG_ERR_DRIVER_SENSE 0x08
|
||||||
|
|
||||||
|
@ -60,7 +60,6 @@
|
|||||||
#define VSCSI_MAX_SECTORS 4096
|
#define VSCSI_MAX_SECTORS 4096
|
||||||
#define VSCSI_REQ_LIMIT 24
|
#define VSCSI_REQ_LIMIT 24
|
||||||
|
|
||||||
#define SCSI_SENSE_BUF_SIZE 96
|
|
||||||
#define SRP_RSP_SENSE_DATA_LEN 18
|
#define SRP_RSP_SENSE_DATA_LEN 18
|
||||||
|
|
||||||
typedef union vscsi_crq {
|
typedef union vscsi_crq {
|
||||||
|
@ -31,7 +31,7 @@ typedef struct SCSISense {
|
|||||||
uint8_t ascq;
|
uint8_t ascq;
|
||||||
} SCSISense;
|
} SCSISense;
|
||||||
|
|
||||||
#define SCSI_SENSE_BUF_SIZE 96
|
#define SCSI_SENSE_BUF_SIZE 252
|
||||||
|
|
||||||
struct SCSICommand {
|
struct SCSICommand {
|
||||||
uint8_t buf[SCSI_CMD_BUF_SIZE];
|
uint8_t buf[SCSI_CMD_BUF_SIZE];
|
||||||
@ -223,6 +223,8 @@ extern const struct SCSISense sense_code_REPORTED_LUNS_CHANGED;
|
|||||||
extern const struct SCSISense sense_code_DEVICE_INTERNAL_RESET;
|
extern const struct SCSISense sense_code_DEVICE_INTERNAL_RESET;
|
||||||
/* Data Protection, Write Protected */
|
/* Data Protection, Write Protected */
|
||||||
extern const struct SCSISense sense_code_WRITE_PROTECTED;
|
extern const struct SCSISense sense_code_WRITE_PROTECTED;
|
||||||
|
/* Data Protection, Space Allocation Failed Write Protect */
|
||||||
|
extern const struct SCSISense sense_code_SPACE_ALLOC_FAILED;
|
||||||
|
|
||||||
#define SENSE_CODE(x) sense_code_ ## x
|
#define SENSE_CODE(x) sense_code_ ## x
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user