mirror of
https://github.com/freebsd/freebsd-src
synced 2024-10-07 17:10:36 +00:00
Really implement PREVENT ALLOW MEDIUM REMOVAL command.
This commit is contained in:
parent
7f3d6f1fe3
commit
66b6967686
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=288369
|
@ -5129,30 +5129,43 @@ ctl_start_stop(struct ctl_scsiio *ctsio)
|
|||
lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
|
||||
cdb = (struct scsi_start_stop_unit *)ctsio->cdb;
|
||||
|
||||
if ((lun->flags & CTL_LUN_PR_RESERVED)
|
||||
&& ((cdb->how & SSS_START)==0)) {
|
||||
uint32_t residx;
|
||||
if ((cdb->how & SSS_PC_MASK) == 0) {
|
||||
if ((lun->flags & CTL_LUN_PR_RESERVED) &&
|
||||
(cdb->how & SSS_START) == 0) {
|
||||
uint32_t residx;
|
||||
|
||||
residx = ctl_get_initindex(&ctsio->io_hdr.nexus);
|
||||
if (ctl_get_prkey(lun, residx) == 0
|
||||
|| (lun->pr_res_idx!=residx && lun->res_type < 4)) {
|
||||
residx = ctl_get_initindex(&ctsio->io_hdr.nexus);
|
||||
if (ctl_get_prkey(lun, residx) == 0 ||
|
||||
(lun->pr_res_idx != residx && lun->res_type < 4)) {
|
||||
|
||||
ctl_set_reservation_conflict(ctsio);
|
||||
ctl_set_reservation_conflict(ctsio);
|
||||
ctl_done((union ctl_io *)ctsio);
|
||||
return (CTL_RETVAL_COMPLETE);
|
||||
}
|
||||
}
|
||||
|
||||
if ((cdb->how & SSS_LOEJ) &&
|
||||
(lun->flags & CTL_LUN_REMOVABLE) == 0) {
|
||||
ctl_set_invalid_field(ctsio,
|
||||
/*sks_valid*/ 1,
|
||||
/*command*/ 1,
|
||||
/*field*/ 4,
|
||||
/*bit_valid*/ 1,
|
||||
/*bit*/ 1);
|
||||
ctl_done((union ctl_io *)ctsio);
|
||||
return (CTL_RETVAL_COMPLETE);
|
||||
}
|
||||
}
|
||||
|
||||
if ((cdb->how & SSS_LOEJ) &&
|
||||
(lun->flags & CTL_LUN_REMOVABLE) == 0) {
|
||||
ctl_set_invalid_field(ctsio,
|
||||
/*sks_valid*/ 1,
|
||||
/*command*/ 1,
|
||||
/*field*/ 4,
|
||||
/*bit_valid*/ 1,
|
||||
/*bit*/ 1);
|
||||
ctl_done((union ctl_io *)ctsio);
|
||||
return (CTL_RETVAL_COMPLETE);
|
||||
if ((cdb->how & SSS_START) == 0 && (cdb->how & SSS_LOEJ) &&
|
||||
lun->prevent_count > 0) {
|
||||
/* "Medium removal prevented" */
|
||||
ctl_set_sense(ctsio, /*current_error*/ 1,
|
||||
/*sense_key*/(lun->flags & CTL_LUN_NO_MEDIA) ?
|
||||
SSD_KEY_NOT_READY : SSD_KEY_ILLEGAL_REQUEST,
|
||||
/*asc*/ 0x53, /*ascq*/ 0x02, SSD_ELEM_NONE);
|
||||
ctl_done((union ctl_io *)ctsio);
|
||||
return (CTL_RETVAL_COMPLETE);
|
||||
}
|
||||
}
|
||||
|
||||
retval = lun->backend->config_write((union ctl_io *)ctsio);
|
||||
|
@ -5163,11 +5176,14 @@ int
|
|||
ctl_prevent_allow(struct ctl_scsiio *ctsio)
|
||||
{
|
||||
struct ctl_lun *lun;
|
||||
struct scsi_prevent *cdb;
|
||||
int retval;
|
||||
uint32_t initidx;
|
||||
|
||||
CTL_DEBUG_PRINT(("ctl_prevent_allow\n"));
|
||||
|
||||
lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
|
||||
cdb = (struct scsi_prevent *)ctsio->cdb;
|
||||
|
||||
if ((lun->flags & CTL_LUN_REMOVABLE) == 0) {
|
||||
ctl_set_invalid_opcode(ctsio);
|
||||
|
@ -5175,6 +5191,18 @@ ctl_prevent_allow(struct ctl_scsiio *ctsio)
|
|||
return (CTL_RETVAL_COMPLETE);
|
||||
}
|
||||
|
||||
initidx = ctl_get_initindex(&ctsio->io_hdr.nexus);
|
||||
mtx_lock(&lun->lun_lock);
|
||||
if ((cdb->how & PR_PREVENT) &&
|
||||
ctl_is_set(lun->prevent, initidx) == 0) {
|
||||
ctl_set_mask(lun->prevent, initidx);
|
||||
lun->prevent_count++;
|
||||
} else if ((cdb->how & PR_PREVENT) == 0 &&
|
||||
ctl_is_set(lun->prevent, initidx)) {
|
||||
ctl_clear_mask(lun->prevent, initidx);
|
||||
lun->prevent_count--;
|
||||
}
|
||||
mtx_unlock(&lun->lun_lock);
|
||||
retval = lun->backend->config_write((union ctl_io *)ctsio);
|
||||
return (retval);
|
||||
}
|
||||
|
@ -11805,9 +11833,7 @@ ctl_do_lun_reset(struct ctl_lun *lun, union ctl_io *io, ctl_ua_type ua_type)
|
|||
#if 0
|
||||
uint32_t initidx;
|
||||
#endif
|
||||
#ifdef CTL_WITH_CA
|
||||
int i;
|
||||
#endif
|
||||
|
||||
mtx_lock(&lun->lun_lock);
|
||||
/*
|
||||
|
@ -11842,6 +11868,9 @@ ctl_do_lun_reset(struct ctl_lun *lun, union ctl_io *io, ctl_ua_type ua_type)
|
|||
for (i = 0; i < CTL_MAX_INITIATORS; i++)
|
||||
ctl_clear_mask(lun->have_ca, i);
|
||||
#endif
|
||||
lun->prevent_count = 0;
|
||||
for (i = 0; i < CTL_MAX_INITIATORS; i++)
|
||||
ctl_clear_mask(lun->prevent, i);
|
||||
mtx_unlock(&lun->lun_lock);
|
||||
|
||||
return (0);
|
||||
|
@ -11987,6 +12016,10 @@ ctl_i_t_nexus_reset(union ctl_io *io)
|
|||
#endif
|
||||
if ((lun->flags & CTL_LUN_RESERVED) && (lun->res_idx == initidx))
|
||||
lun->flags &= ~CTL_LUN_RESERVED;
|
||||
if (ctl_is_set(lun->prevent, initidx)) {
|
||||
ctl_clear_mask(lun->prevent, initidx);
|
||||
lun->prevent_count--;
|
||||
}
|
||||
ctl_est_ua(lun, initidx, CTL_UA_I_T_NEXUS_LOSS);
|
||||
mtx_unlock(&lun->lun_lock);
|
||||
}
|
||||
|
|
|
@ -2754,6 +2754,11 @@ ctl_be_block_config_write(union ctl_io *io)
|
|||
struct ctl_lun_req req;
|
||||
|
||||
cdb = (struct scsi_start_stop_unit *)io->scsiio.cdb;
|
||||
if ((cdb->how & SSS_PC_MASK) != 0) {
|
||||
ctl_set_success(&io->scsiio);
|
||||
ctl_config_write_done(io);
|
||||
break;
|
||||
}
|
||||
if (cdb->how & SSS_START) {
|
||||
if ((cdb->how & SSS_LOEJ) && be_lun->vn == NULL) {
|
||||
retval = ctl_be_block_open(be_lun, &req);
|
||||
|
|
|
@ -880,6 +880,11 @@ ctl_backend_ramdisk_config_write(union ctl_io *io)
|
|||
struct scsi_start_stop_unit *cdb;
|
||||
|
||||
cdb = (struct scsi_start_stop_unit *)io->scsiio.cdb;
|
||||
if ((cdb->how & SSS_PC_MASK) != 0) {
|
||||
ctl_set_success(&io->scsiio);
|
||||
ctl_config_write_done(io);
|
||||
break;
|
||||
}
|
||||
if (cdb->how & SSS_START) {
|
||||
if (cdb->how & SSS_LOEJ)
|
||||
ctl_lun_has_media(cbe_lun);
|
||||
|
|
|
@ -658,7 +658,7 @@ const struct ctl_cmd_entry ctl_cmd_table[256] =
|
|||
CTL_CMD_FLAG_OK_ON_NO_MEDIA |
|
||||
CTL_FLAG_DATA_NONE |
|
||||
CTL_CMD_FLAG_ALLOW_ON_PR_RESV,
|
||||
CTL_LUN_PAT_NONE, 6, {0x01, 0, 0, 0x03, 0x07}},
|
||||
CTL_LUN_PAT_NONE, 6, {0x01, 0, 0x0f, 0xf7, 0x07}},
|
||||
|
||||
/* 1C RECEIVE DIAGNOSTIC RESULTS */
|
||||
{NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE},
|
||||
|
|
|
@ -397,6 +397,8 @@ struct ctl_lun {
|
|||
int pr_key_count;
|
||||
uint32_t pr_res_idx;
|
||||
uint8_t res_type;
|
||||
int prevent_count;
|
||||
uint32_t prevent[(CTL_MAX_INITIATORS+31)/32];
|
||||
uint8_t *write_buffer;
|
||||
struct ctl_devid *lun_devid;
|
||||
TAILQ_HEAD(tpc_lists, tpc_list) tpc_lists;
|
||||
|
|
Loading…
Reference in a new issue