Add to CTL initial support for CDROMs and removable devices.
Relnotes: yes
This commit is contained in:
parent
3caeab9db2
commit
91be33dc78
@ -24,7 +24,7 @@
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.Dd September 12, 2015
|
||||
.Dd September 27, 2015
|
||||
.Dt CTL 4
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -53,7 +53,7 @@ It supports features such as:
|
||||
.Pp
|
||||
.Bl -bullet -compact
|
||||
.It
|
||||
Disk and processor device emulation
|
||||
Disk, processor and cdrom device emulation
|
||||
.It
|
||||
Tagged queueing
|
||||
.It
|
||||
|
@ -19,9 +19,9 @@ Userland Commands
|
||||
Introduction:
|
||||
============
|
||||
|
||||
CTL is a disk and processor device emulation subsystem originally written
|
||||
for Copan Systems under Linux starting in 2003. It has been shipping in
|
||||
Copan (now SGI) products since 2005.
|
||||
CTL is a disk, processor and cdrom device emulation subsystem originally
|
||||
written for Copan Systems under Linux starting in 2003. It has been
|
||||
shipping in Copan (now SGI) products since 2005.
|
||||
|
||||
It was ported to FreeBSD in 2008, and thanks to an agreement between SGI
|
||||
(who acquired Copan's assets in 2010) and Spectra Logic in 2010, CTL is
|
||||
@ -31,7 +31,7 @@ that Spectra would work to get CTL into the FreeBSD tree.
|
||||
Features:
|
||||
========
|
||||
|
||||
- Disk and processor device emulation.
|
||||
- Disk, processor and cdrom device emulation.
|
||||
- Tagged queueing
|
||||
- SCSI task attribute support (ordered, head of queue, simple tags)
|
||||
- SCSI implicit command ordering support. (e.g. if a read follows a mode
|
||||
|
@ -69,6 +69,7 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#include <cam/cam.h>
|
||||
#include <cam/scsi/scsi_all.h>
|
||||
#include <cam/scsi/scsi_cd.h>
|
||||
#include <cam/scsi/scsi_da.h>
|
||||
#include <cam/ctl/ctl_io.h>
|
||||
#include <cam/ctl/ctl.h>
|
||||
@ -3819,8 +3820,14 @@ ctl_init_page_index(struct ctl_lun *lun)
|
||||
for (i = 0; i < CTL_NUM_MODE_PAGES; i++) {
|
||||
|
||||
page_index = &lun->mode_pages.index[i];
|
||||
if (lun->be_lun->lun_type != T_DIRECT &&
|
||||
(page_index->page_flags & CTL_PAGE_FLAG_DISK_ONLY))
|
||||
if (lun->be_lun->lun_type == T_DIRECT &&
|
||||
(page_index->page_flags & CTL_PAGE_FLAG_DIRECT) == 0)
|
||||
continue;
|
||||
if (lun->be_lun->lun_type == T_PROCESSOR &&
|
||||
(page_index->page_flags & CTL_PAGE_FLAG_PROC) == 0)
|
||||
continue;
|
||||
if (lun->be_lun->lun_type == T_CDROM &&
|
||||
(page_index->page_flags & CTL_PAGE_FLAG_CDROM) == 0)
|
||||
continue;
|
||||
|
||||
switch (page_index->page_code & SMPH_PC_MASK) {
|
||||
@ -4205,8 +4212,14 @@ ctl_init_log_page_index(struct ctl_lun *lun)
|
||||
for (i = 0, j = 0, k = 0; i < CTL_NUM_LOG_PAGES; i++) {
|
||||
|
||||
page_index = &lun->log_pages.index[i];
|
||||
if (lun->be_lun->lun_type != T_DIRECT &&
|
||||
(page_index->page_flags & CTL_PAGE_FLAG_DISK_ONLY))
|
||||
if (lun->be_lun->lun_type == T_DIRECT &&
|
||||
(page_index->page_flags & CTL_PAGE_FLAG_DIRECT) == 0)
|
||||
continue;
|
||||
if (lun->be_lun->lun_type == T_PROCESSOR &&
|
||||
(page_index->page_flags & CTL_PAGE_FLAG_PROC) == 0)
|
||||
continue;
|
||||
if (lun->be_lun->lun_type == T_CDROM &&
|
||||
(page_index->page_flags & CTL_PAGE_FLAG_CDROM) == 0)
|
||||
continue;
|
||||
|
||||
if (page_index->page_code == SLS_LOGICAL_BLOCK_PROVISIONING &&
|
||||
@ -4282,7 +4295,7 @@ ctl_alloc_lun(struct ctl_softc *ctl_softc, struct ctl_lun *ctl_lun,
|
||||
struct ctl_lun *nlun, *lun;
|
||||
struct scsi_vpd_id_descriptor *desc;
|
||||
struct scsi_vpd_id_t10 *t10id;
|
||||
const char *eui, *naa, *scsiname, *vendor;
|
||||
const char *eui, *naa, *scsiname, *vendor, *value;
|
||||
int lun_number, i, lun_malloced;
|
||||
int devidlen, idlen1, idlen2 = 0, len;
|
||||
|
||||
@ -4294,8 +4307,8 @@ ctl_alloc_lun(struct ctl_softc *ctl_softc, struct ctl_lun *ctl_lun,
|
||||
*/
|
||||
switch (be_lun->lun_type) {
|
||||
case T_DIRECT:
|
||||
break;
|
||||
case T_PROCESSOR:
|
||||
case T_CDROM:
|
||||
break;
|
||||
case T_SEQUENTIAL:
|
||||
case T_CHANGER:
|
||||
@ -4448,6 +4461,13 @@ ctl_alloc_lun(struct ctl_softc *ctl_softc, struct ctl_lun *ctl_lun,
|
||||
if (be_lun->flags & CTL_LUN_FLAG_PRIMARY)
|
||||
lun->flags |= CTL_LUN_PRIMARY_SC;
|
||||
|
||||
value = ctl_get_opt(&be_lun->options, "removable");
|
||||
if (value != NULL) {
|
||||
if (strcmp(value, "on") == 0)
|
||||
lun->flags |= CTL_LUN_REMOVABLE;
|
||||
} else if (be_lun->lun_type == T_CDROM)
|
||||
lun->flags |= CTL_LUN_REMOVABLE;
|
||||
|
||||
lun->ctl_softc = ctl_softc;
|
||||
#ifdef CTL_TIME_IO
|
||||
lun->last_busy = getsbinuptime();
|
||||
@ -5124,14 +5144,14 @@ ctl_start_stop(struct ctl_scsiio *ctsio)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If there is no backend on this device, we can't start or stop
|
||||
* it. In theory we shouldn't get any start/stop commands in the
|
||||
* first place at this level if the LUN doesn't have a backend.
|
||||
* That should get stopped by the command decode code.
|
||||
*/
|
||||
if (lun->backend == NULL) {
|
||||
ctl_set_invalid_opcode(ctsio);
|
||||
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);
|
||||
}
|
||||
@ -5161,6 +5181,26 @@ ctl_start_stop(struct ctl_scsiio *ctsio)
|
||||
return (retval);
|
||||
}
|
||||
|
||||
int
|
||||
ctl_prevent_allow(struct ctl_scsiio *ctsio)
|
||||
{
|
||||
struct ctl_lun *lun;
|
||||
int retval;
|
||||
|
||||
CTL_DEBUG_PRINT(("ctl_prevent_allow\n"));
|
||||
|
||||
lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
|
||||
|
||||
if ((lun->flags & CTL_LUN_REMOVABLE) == 0) {
|
||||
ctl_set_invalid_opcode(ctsio);
|
||||
ctl_done((union ctl_io *)ctsio);
|
||||
return (CTL_RETVAL_COMPLETE);
|
||||
}
|
||||
|
||||
retval = lun->backend->config_write((union ctl_io *)ctsio);
|
||||
return (retval);
|
||||
}
|
||||
|
||||
/*
|
||||
* We support the SYNCHRONIZE CACHE command (10 and 16 byte versions), but
|
||||
* we don't really do anything with the LBA and length fields if the user
|
||||
@ -5222,15 +5262,6 @@ ctl_sync_cache(struct ctl_scsiio *ctsio)
|
||||
goto bailout;
|
||||
}
|
||||
|
||||
/*
|
||||
* If this LUN has no backend, we can't flush the cache anyway.
|
||||
*/
|
||||
if (lun->backend == NULL) {
|
||||
ctl_set_invalid_opcode(ctsio);
|
||||
ctl_done((union ctl_io *)ctsio);
|
||||
goto bailout;
|
||||
}
|
||||
|
||||
lbalen = (struct ctl_lba_len_flags *)&ctsio->io_hdr.ctl_private[CTL_PRIV_LBA_LEN];
|
||||
lbalen->lba = starting_lba;
|
||||
lbalen->len = block_count;
|
||||
@ -5933,13 +5964,18 @@ ctl_do_mode_select(union ctl_io *io)
|
||||
* XXX KDM should we do something with the block descriptor?
|
||||
*/
|
||||
for (i = 0; i < CTL_NUM_MODE_PAGES; i++) {
|
||||
|
||||
if (lun->be_lun->lun_type != T_DIRECT &&
|
||||
(lun->mode_pages.index[i].page_flags &
|
||||
CTL_PAGE_FLAG_DISK_ONLY))
|
||||
page_index = &lun->mode_pages.index[i];
|
||||
if (lun->be_lun->lun_type == T_DIRECT &&
|
||||
(page_index->page_flags & CTL_PAGE_FLAG_DIRECT) == 0)
|
||||
continue;
|
||||
if (lun->be_lun->lun_type == T_PROCESSOR &&
|
||||
(page_index->page_flags & CTL_PAGE_FLAG_PROC) == 0)
|
||||
continue;
|
||||
if (lun->be_lun->lun_type == T_CDROM &&
|
||||
(page_index->page_flags & CTL_PAGE_FLAG_CDROM) == 0)
|
||||
continue;
|
||||
|
||||
if ((lun->mode_pages.index[i].page_code & SMPH_PC_MASK) !=
|
||||
if ((page_index->page_code & SMPH_PC_MASK) !=
|
||||
(page_header->page_code & SMPH_PC_MASK))
|
||||
continue;
|
||||
|
||||
@ -5947,9 +5983,8 @@ ctl_do_mode_select(union ctl_io *io)
|
||||
* If neither page has a subpage code, then we've got a
|
||||
* match.
|
||||
*/
|
||||
if (((lun->mode_pages.index[i].page_code & SMPH_SPF) == 0)
|
||||
if (((page_index->page_code & SMPH_SPF) == 0)
|
||||
&& ((page_header->page_code & SMPH_SPF) == 0)) {
|
||||
page_index = &lun->mode_pages.index[i];
|
||||
page_len = page_header->page_length;
|
||||
break;
|
||||
}
|
||||
@ -5958,15 +5993,12 @@ ctl_do_mode_select(union ctl_io *io)
|
||||
* If both pages have subpages, then the subpage numbers
|
||||
* have to match.
|
||||
*/
|
||||
if ((lun->mode_pages.index[i].page_code & SMPH_SPF)
|
||||
if ((page_index->page_code & SMPH_SPF)
|
||||
&& (page_header->page_code & SMPH_SPF)) {
|
||||
struct scsi_mode_page_header_sp *sph;
|
||||
|
||||
sph = (struct scsi_mode_page_header_sp *)page_header;
|
||||
|
||||
if (lun->mode_pages.index[i].subpage ==
|
||||
sph->subpage) {
|
||||
page_index = &lun->mode_pages.index[i];
|
||||
if (page_index->subpage == sph->subpage) {
|
||||
page_len = scsi_2btoul(sph->page_length);
|
||||
break;
|
||||
}
|
||||
@ -5977,7 +6009,7 @@ ctl_do_mode_select(union ctl_io *io)
|
||||
* If we couldn't find the page, or if we don't have a mode select
|
||||
* handler for it, send back an error to the user.
|
||||
*/
|
||||
if ((page_index == NULL)
|
||||
if ((i >= CTL_NUM_MODE_PAGES)
|
||||
|| (page_index->select_handler == NULL)) {
|
||||
ctl_set_invalid_field(ctsio,
|
||||
/*sks_valid*/ 1,
|
||||
@ -6236,7 +6268,6 @@ ctl_mode_sense(struct ctl_scsiio *ctsio)
|
||||
dbd = 0;
|
||||
llba = 0;
|
||||
block_desc = NULL;
|
||||
page_index = NULL;
|
||||
|
||||
CTL_DEBUG_PRINT(("ctl_mode_sense\n"));
|
||||
|
||||
@ -6313,26 +6344,33 @@ ctl_mode_sense(struct ctl_scsiio *ctsio)
|
||||
}
|
||||
|
||||
for (i = 0; i < CTL_NUM_MODE_PAGES; i++) {
|
||||
if (lun->be_lun->lun_type != T_DIRECT &&
|
||||
(lun->mode_pages.index[i].page_flags &
|
||||
CTL_PAGE_FLAG_DISK_ONLY))
|
||||
page_index = &lun->mode_pages.index[i];
|
||||
|
||||
/* Make sure the page is supported for this dev type */
|
||||
if (lun->be_lun->lun_type == T_DIRECT &&
|
||||
(page_index->page_flags & CTL_PAGE_FLAG_DIRECT) == 0)
|
||||
continue;
|
||||
if (lun->be_lun->lun_type == T_PROCESSOR &&
|
||||
(page_index->page_flags & CTL_PAGE_FLAG_PROC) == 0)
|
||||
continue;
|
||||
if (lun->be_lun->lun_type == T_CDROM &&
|
||||
(page_index->page_flags & CTL_PAGE_FLAG_CDROM) == 0)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* We don't use this subpage if the user didn't
|
||||
* request all subpages.
|
||||
*/
|
||||
if ((lun->mode_pages.index[i].subpage != 0)
|
||||
if ((page_index->subpage != 0)
|
||||
&& (subpage == SMS_SUBPAGE_PAGE_0))
|
||||
continue;
|
||||
|
||||
#if 0
|
||||
printf("found page %#x len %d\n",
|
||||
lun->mode_pages.index[i].page_code &
|
||||
SMPH_PC_MASK,
|
||||
lun->mode_pages.index[i].page_len);
|
||||
page_index->page_code & SMPH_PC_MASK,
|
||||
page_index->page_len);
|
||||
#endif
|
||||
page_len += lun->mode_pages.index[i].page_len;
|
||||
page_len += page_index->page_len;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -6342,30 +6380,35 @@ ctl_mode_sense(struct ctl_scsiio *ctsio)
|
||||
page_len = 0;
|
||||
|
||||
for (i = 0; i < CTL_NUM_MODE_PAGES; i++) {
|
||||
page_index = &lun->mode_pages.index[i];
|
||||
|
||||
/* Make sure the page is supported for this dev type */
|
||||
if (lun->be_lun->lun_type == T_DIRECT &&
|
||||
(page_index->page_flags & CTL_PAGE_FLAG_DIRECT) == 0)
|
||||
continue;
|
||||
if (lun->be_lun->lun_type == T_PROCESSOR &&
|
||||
(page_index->page_flags & CTL_PAGE_FLAG_PROC) == 0)
|
||||
continue;
|
||||
if (lun->be_lun->lun_type == T_CDROM &&
|
||||
(page_index->page_flags & CTL_PAGE_FLAG_CDROM) == 0)
|
||||
continue;
|
||||
|
||||
/* Look for the right page code */
|
||||
if ((lun->mode_pages.index[i].page_code &
|
||||
SMPH_PC_MASK) != page_code)
|
||||
if ((page_index->page_code & SMPH_PC_MASK) != page_code)
|
||||
continue;
|
||||
|
||||
/* Look for the right subpage or the subpage wildcard*/
|
||||
if ((lun->mode_pages.index[i].subpage != subpage)
|
||||
if ((page_index->subpage != subpage)
|
||||
&& (subpage != SMS_SUBPAGE_ALL))
|
||||
continue;
|
||||
|
||||
/* Make sure the page is supported for this dev type */
|
||||
if (lun->be_lun->lun_type != T_DIRECT &&
|
||||
(lun->mode_pages.index[i].page_flags &
|
||||
CTL_PAGE_FLAG_DISK_ONLY))
|
||||
continue;
|
||||
|
||||
#if 0
|
||||
printf("found page %#x len %d\n",
|
||||
lun->mode_pages.index[i].page_code &
|
||||
SMPH_PC_MASK,
|
||||
lun->mode_pages.index[i].page_len);
|
||||
page_index->page_code & SMPH_PC_MASK,
|
||||
page_index->page_len);
|
||||
#endif
|
||||
|
||||
page_len += lun->mode_pages.index[i].page_len;
|
||||
page_len += page_index->page_len;
|
||||
}
|
||||
|
||||
if (page_len == 0) {
|
||||
@ -6473,9 +6516,14 @@ ctl_mode_sense(struct ctl_scsiio *ctsio)
|
||||
struct ctl_page_index *page_index;
|
||||
|
||||
page_index = &lun->mode_pages.index[i];
|
||||
|
||||
if (lun->be_lun->lun_type != T_DIRECT &&
|
||||
(page_index->page_flags & CTL_PAGE_FLAG_DISK_ONLY))
|
||||
if (lun->be_lun->lun_type == T_DIRECT &&
|
||||
(page_index->page_flags & CTL_PAGE_FLAG_DIRECT) == 0)
|
||||
continue;
|
||||
if (lun->be_lun->lun_type == T_PROCESSOR &&
|
||||
(page_index->page_flags & CTL_PAGE_FLAG_PROC) == 0)
|
||||
continue;
|
||||
if (lun->be_lun->lun_type == T_CDROM &&
|
||||
(page_index->page_flags & CTL_PAGE_FLAG_CDROM) == 0)
|
||||
continue;
|
||||
|
||||
/*
|
||||
@ -6523,8 +6571,14 @@ ctl_mode_sense(struct ctl_scsiio *ctsio)
|
||||
continue;
|
||||
|
||||
/* Make sure the page is supported for this dev type */
|
||||
if (lun->be_lun->lun_type != T_DIRECT &&
|
||||
(page_index->page_flags & CTL_PAGE_FLAG_DISK_ONLY))
|
||||
if (lun->be_lun->lun_type == T_DIRECT &&
|
||||
(page_index->page_flags & CTL_PAGE_FLAG_DIRECT) == 0)
|
||||
continue;
|
||||
if (lun->be_lun->lun_type == T_PROCESSOR &&
|
||||
(page_index->page_flags & CTL_PAGE_FLAG_PROC) == 0)
|
||||
continue;
|
||||
if (lun->be_lun->lun_type == T_CDROM &&
|
||||
(page_index->page_flags & CTL_PAGE_FLAG_CDROM) == 0)
|
||||
continue;
|
||||
|
||||
/*
|
||||
@ -10050,6 +10104,8 @@ ctl_inquiry_std(struct ctl_scsiio *ctsio)
|
||||
inq_ptr->device = (SID_QUAL_LU_OFFLINE << 5) |
|
||||
lun->be_lun->lun_type;
|
||||
}
|
||||
if (lun->flags & CTL_LUN_REMOVABLE)
|
||||
inq_ptr->dev_qual2 |= SID_RMB;
|
||||
} else
|
||||
inq_ptr->device = (SID_QUAL_BAD_LU << 5) | T_NODEVICE;
|
||||
|
||||
@ -10114,6 +10170,10 @@ ctl_inquiry_std(struct ctl_scsiio *ctsio)
|
||||
strncpy(inq_ptr->product, CTL_PROCESSOR_PRODUCT,
|
||||
sizeof(inq_ptr->product));
|
||||
break;
|
||||
case T_CDROM:
|
||||
strncpy(inq_ptr->product, CTL_CDROM_PRODUCT,
|
||||
sizeof(inq_ptr->product));
|
||||
break;
|
||||
default:
|
||||
strncpy(inq_ptr->product, CTL_UNKNOWN_PRODUCT,
|
||||
sizeof(inq_ptr->product));
|
||||
@ -10176,6 +10236,11 @@ ctl_inquiry_std(struct ctl_scsiio *ctsio)
|
||||
scsi_ulto2b(0x0600, inq_ptr->version4);
|
||||
break;
|
||||
case T_PROCESSOR:
|
||||
break;
|
||||
case T_CDROM:
|
||||
/* MMC-6 (no version claimed) */
|
||||
scsi_ulto2b(0x04E0, inq_ptr->version4);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -10215,6 +10280,344 @@ ctl_inquiry(struct ctl_scsiio *ctsio)
|
||||
return (retval);
|
||||
}
|
||||
|
||||
int
|
||||
ctl_get_config(struct ctl_scsiio *ctsio)
|
||||
{
|
||||
struct scsi_get_config_header *hdr;
|
||||
struct scsi_get_config_feature *feature;
|
||||
struct scsi_get_config *cdb;
|
||||
struct ctl_lun *lun;
|
||||
uint32_t alloc_len, data_len;
|
||||
int rt, starting;
|
||||
|
||||
lun = ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
|
||||
cdb = (struct scsi_get_config *)ctsio->cdb;
|
||||
rt = (cdb->rt & SGC_RT_MASK);
|
||||
starting = scsi_2btoul(cdb->starting_feature);
|
||||
alloc_len = scsi_2btoul(cdb->length);
|
||||
|
||||
data_len = sizeof(struct scsi_get_config_header) +
|
||||
sizeof(struct scsi_get_config_feature) + 8 +
|
||||
sizeof(struct scsi_get_config_feature) + 8 +
|
||||
sizeof(struct scsi_get_config_feature) + 4 +
|
||||
sizeof(struct scsi_get_config_feature) + 4 +
|
||||
sizeof(struct scsi_get_config_feature) + 8 +
|
||||
sizeof(struct scsi_get_config_feature) +
|
||||
sizeof(struct scsi_get_config_feature) + 4 +
|
||||
sizeof(struct scsi_get_config_feature) + 4;
|
||||
ctsio->kern_data_ptr = malloc(data_len, M_CTL, M_WAITOK | M_ZERO);
|
||||
ctsio->kern_sg_entries = 0;
|
||||
ctsio->kern_data_resid = 0;
|
||||
ctsio->kern_rel_offset = 0;
|
||||
|
||||
hdr = (struct scsi_get_config_header *)ctsio->kern_data_ptr;
|
||||
if (lun->flags & CTL_LUN_OFFLINE)
|
||||
scsi_ulto2b(0x0000, hdr->current_profile);
|
||||
else
|
||||
scsi_ulto2b(0x0010, hdr->current_profile);
|
||||
feature = (struct scsi_get_config_feature *)(hdr + 1);
|
||||
|
||||
if (starting > 0x001f)
|
||||
goto done;
|
||||
if (starting > 0x001e)
|
||||
goto f1f;
|
||||
if (starting > 0x001d)
|
||||
goto f1e;
|
||||
if (starting > 0x0010)
|
||||
goto f1d;
|
||||
if (starting > 0x0003)
|
||||
goto f10;
|
||||
if (starting > 0x0002)
|
||||
goto f3;
|
||||
if (starting > 0x0001)
|
||||
goto f2;
|
||||
if (starting > 0x0000)
|
||||
goto f1;
|
||||
|
||||
/* Profile List */
|
||||
scsi_ulto2b(0x0000, feature->feature_code);
|
||||
feature->flags = SGC_F_PERSISTENT | SGC_F_CURRENT;
|
||||
feature->add_length = 8;
|
||||
scsi_ulto2b(0x0008, &feature->feature_data[0]); /* CD-ROM */
|
||||
feature->feature_data[2] = 0x00;
|
||||
scsi_ulto2b(0x0010, &feature->feature_data[4]); /* DVD-ROM */
|
||||
feature->feature_data[6] = 0x01;
|
||||
feature = (struct scsi_get_config_feature *)
|
||||
&feature->feature_data[feature->add_length];
|
||||
|
||||
f1: /* Core */
|
||||
scsi_ulto2b(0x0001, feature->feature_code);
|
||||
feature->flags = 0x08 | SGC_F_PERSISTENT | SGC_F_CURRENT;
|
||||
feature->add_length = 8;
|
||||
scsi_ulto4b(0x00000000, &feature->feature_data[0]);
|
||||
feature->feature_data[4] = 0x03;
|
||||
feature = (struct scsi_get_config_feature *)
|
||||
&feature->feature_data[feature->add_length];
|
||||
|
||||
f2: /* Morphing */
|
||||
scsi_ulto2b(0x0002, feature->feature_code);
|
||||
feature->flags = 0x04 | SGC_F_PERSISTENT | SGC_F_CURRENT;
|
||||
feature->add_length = 4;
|
||||
feature->feature_data[0] = 0x02;
|
||||
feature = (struct scsi_get_config_feature *)
|
||||
&feature->feature_data[feature->add_length];
|
||||
|
||||
f3: /* Removable Medium */
|
||||
scsi_ulto2b(0x0003, feature->feature_code);
|
||||
feature->flags = 0x04 | SGC_F_PERSISTENT | SGC_F_CURRENT;
|
||||
feature->add_length = 4;
|
||||
feature->feature_data[0] = 0x39;
|
||||
feature = (struct scsi_get_config_feature *)
|
||||
&feature->feature_data[feature->add_length];
|
||||
|
||||
if (rt == SGC_RT_CURRENT && (lun->flags & CTL_LUN_OFFLINE))
|
||||
goto done;
|
||||
|
||||
f10: /* Random Read */
|
||||
scsi_ulto2b(0x0010, feature->feature_code);
|
||||
feature->flags = 0x00;
|
||||
if ((lun->flags & CTL_LUN_OFFLINE) == 0)
|
||||
feature->flags |= SGC_F_CURRENT;
|
||||
feature->add_length = 8;
|
||||
scsi_ulto4b(lun->be_lun->blocksize, &feature->feature_data[0]);
|
||||
scsi_ulto2b(1, &feature->feature_data[4]);
|
||||
feature->feature_data[6] = 0x00;
|
||||
feature = (struct scsi_get_config_feature *)
|
||||
&feature->feature_data[feature->add_length];
|
||||
|
||||
f1d: /* Multi-Read */
|
||||
scsi_ulto2b(0x001D, feature->feature_code);
|
||||
feature->flags = 0x00;
|
||||
if ((lun->flags & CTL_LUN_OFFLINE) == 0)
|
||||
feature->flags |= SGC_F_CURRENT;
|
||||
feature->add_length = 0;
|
||||
feature = (struct scsi_get_config_feature *)
|
||||
&feature->feature_data[feature->add_length];
|
||||
|
||||
f1e: /* CD Read */
|
||||
scsi_ulto2b(0x001E, feature->feature_code);
|
||||
feature->flags = 0x00;
|
||||
if ((lun->flags & CTL_LUN_OFFLINE) == 0)
|
||||
feature->flags |= SGC_F_CURRENT;
|
||||
feature->add_length = 4;
|
||||
feature->feature_data[0] = 0x00;
|
||||
feature = (struct scsi_get_config_feature *)
|
||||
&feature->feature_data[feature->add_length];
|
||||
|
||||
f1f: /* DVD Read */
|
||||
scsi_ulto2b(0x001F, feature->feature_code);
|
||||
feature->flags = 0x08;
|
||||
if ((lun->flags & CTL_LUN_OFFLINE) == 0)
|
||||
feature->flags |= SGC_F_CURRENT;
|
||||
feature->add_length = 4;
|
||||
feature->feature_data[0] = 0x01;
|
||||
feature->feature_data[2] = 0x03;
|
||||
feature = (struct scsi_get_config_feature *)
|
||||
&feature->feature_data[feature->add_length];
|
||||
|
||||
done:
|
||||
data_len = (uint8_t *)feature - (uint8_t *)hdr;
|
||||
if (rt == SGC_RT_SPECIFIC && data_len > 4) {
|
||||
feature = (struct scsi_get_config_feature *)(hdr + 1);
|
||||
if (scsi_2btoul(feature->feature_code) == starting)
|
||||
feature = (struct scsi_get_config_feature *)
|
||||
&feature->feature_data[feature->add_length];
|
||||
data_len = (uint8_t *)feature - (uint8_t *)hdr;
|
||||
}
|
||||
scsi_ulto4b(data_len - 4, hdr->data_length);
|
||||
if (data_len < alloc_len) {
|
||||
ctsio->residual = alloc_len - data_len;
|
||||
ctsio->kern_data_len = data_len;
|
||||
ctsio->kern_total_len = data_len;
|
||||
} else {
|
||||
ctsio->residual = 0;
|
||||
ctsio->kern_data_len = alloc_len;
|
||||
ctsio->kern_total_len = alloc_len;
|
||||
}
|
||||
|
||||
ctl_set_success(ctsio);
|
||||
ctsio->io_hdr.flags |= CTL_FLAG_ALLOCATED;
|
||||
ctsio->be_move_done = ctl_config_move_done;
|
||||
ctl_datamove((union ctl_io *)ctsio);
|
||||
return (CTL_RETVAL_COMPLETE);
|
||||
}
|
||||
|
||||
int
|
||||
ctl_get_event_status(struct ctl_scsiio *ctsio)
|
||||
{
|
||||
struct scsi_get_event_status_header *hdr;
|
||||
struct scsi_get_event_status *cdb;
|
||||
struct ctl_lun *lun;
|
||||
uint32_t alloc_len, data_len;
|
||||
int notif_class;
|
||||
|
||||
lun = ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
|
||||
cdb = (struct scsi_get_event_status *)ctsio->cdb;
|
||||
if ((cdb->byte2 & SGESN_POLLED) == 0) {
|
||||
ctl_set_invalid_field(ctsio, /*sks_valid*/ 1, /*command*/ 1,
|
||||
/*field*/ 1, /*bit_valid*/ 1, /*bit*/ 0);
|
||||
ctl_done((union ctl_io *)ctsio);
|
||||
return (CTL_RETVAL_COMPLETE);
|
||||
}
|
||||
notif_class = cdb->notif_class;
|
||||
alloc_len = scsi_2btoul(cdb->length);
|
||||
|
||||
data_len = sizeof(struct scsi_get_event_status_header);
|
||||
ctsio->kern_data_ptr = malloc(data_len, M_CTL, M_WAITOK | M_ZERO);
|
||||
ctsio->kern_sg_entries = 0;
|
||||
ctsio->kern_data_resid = 0;
|
||||
ctsio->kern_rel_offset = 0;
|
||||
|
||||
if (data_len < alloc_len) {
|
||||
ctsio->residual = alloc_len - data_len;
|
||||
ctsio->kern_data_len = data_len;
|
||||
ctsio->kern_total_len = data_len;
|
||||
} else {
|
||||
ctsio->residual = 0;
|
||||
ctsio->kern_data_len = alloc_len;
|
||||
ctsio->kern_total_len = alloc_len;
|
||||
}
|
||||
|
||||
hdr = (struct scsi_get_event_status_header *)ctsio->kern_data_ptr;
|
||||
scsi_ulto2b(0, hdr->descr_length);
|
||||
hdr->nea_class = SGESN_NEA;
|
||||
hdr->supported_class = 0;
|
||||
|
||||
ctl_set_success(ctsio);
|
||||
ctsio->io_hdr.flags |= CTL_FLAG_ALLOCATED;
|
||||
ctsio->be_move_done = ctl_config_move_done;
|
||||
ctl_datamove((union ctl_io *)ctsio);
|
||||
return (CTL_RETVAL_COMPLETE);
|
||||
}
|
||||
|
||||
int
|
||||
ctl_mechanism_status(struct ctl_scsiio *ctsio)
|
||||
{
|
||||
struct scsi_mechanism_status_header *hdr;
|
||||
struct scsi_mechanism_status *cdb;
|
||||
struct ctl_lun *lun;
|
||||
uint32_t alloc_len, data_len;
|
||||
|
||||
lun = ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
|
||||
cdb = (struct scsi_mechanism_status *)ctsio->cdb;
|
||||
alloc_len = scsi_2btoul(cdb->length);
|
||||
|
||||
data_len = sizeof(struct scsi_mechanism_status_header);
|
||||
ctsio->kern_data_ptr = malloc(data_len, M_CTL, M_WAITOK | M_ZERO);
|
||||
ctsio->kern_sg_entries = 0;
|
||||
ctsio->kern_data_resid = 0;
|
||||
ctsio->kern_rel_offset = 0;
|
||||
|
||||
if (data_len < alloc_len) {
|
||||
ctsio->residual = alloc_len - data_len;
|
||||
ctsio->kern_data_len = data_len;
|
||||
ctsio->kern_total_len = data_len;
|
||||
} else {
|
||||
ctsio->residual = 0;
|
||||
ctsio->kern_data_len = alloc_len;
|
||||
ctsio->kern_total_len = alloc_len;
|
||||
}
|
||||
|
||||
hdr = (struct scsi_mechanism_status_header *)ctsio->kern_data_ptr;
|
||||
hdr->state1 = 0x00;
|
||||
hdr->state2 = 0xe0;
|
||||
scsi_ulto3b(0, hdr->lba);
|
||||
hdr->slots_num = 0;
|
||||
scsi_ulto2b(0, hdr->slots_length);
|
||||
|
||||
ctl_set_success(ctsio);
|
||||
ctsio->io_hdr.flags |= CTL_FLAG_ALLOCATED;
|
||||
ctsio->be_move_done = ctl_config_move_done;
|
||||
ctl_datamove((union ctl_io *)ctsio);
|
||||
return (CTL_RETVAL_COMPLETE);
|
||||
}
|
||||
|
||||
static void
|
||||
ctl_ultomsf(uint32_t lba, uint8_t *buf)
|
||||
{
|
||||
|
||||
lba += 150;
|
||||
buf[0] = 0;
|
||||
buf[1] = bin2bcd((lba / 75) / 60);
|
||||
buf[2] = bin2bcd((lba / 75) % 60);
|
||||
buf[3] = bin2bcd(lba % 75);
|
||||
}
|
||||
|
||||
int
|
||||
ctl_read_toc(struct ctl_scsiio *ctsio)
|
||||
{
|
||||
struct scsi_read_toc_hdr *hdr;
|
||||
struct scsi_read_toc_type01_descr *descr;
|
||||
struct scsi_read_toc *cdb;
|
||||
struct ctl_lun *lun;
|
||||
uint32_t alloc_len, data_len;
|
||||
int format, msf;
|
||||
|
||||
lun = ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
|
||||
cdb = (struct scsi_read_toc *)ctsio->cdb;
|
||||
msf = (cdb->byte2 & CD_MSF) != 0;
|
||||
format = cdb->format;
|
||||
alloc_len = scsi_2btoul(cdb->data_len);
|
||||
|
||||
data_len = sizeof(struct scsi_read_toc_hdr);
|
||||
if (format == 0)
|
||||
data_len += 2 * sizeof(struct scsi_read_toc_type01_descr);
|
||||
else
|
||||
data_len += sizeof(struct scsi_read_toc_type01_descr);
|
||||
ctsio->kern_data_ptr = malloc(data_len, M_CTL, M_WAITOK | M_ZERO);
|
||||
ctsio->kern_sg_entries = 0;
|
||||
ctsio->kern_data_resid = 0;
|
||||
ctsio->kern_rel_offset = 0;
|
||||
|
||||
if (data_len < alloc_len) {
|
||||
ctsio->residual = alloc_len - data_len;
|
||||
ctsio->kern_data_len = data_len;
|
||||
ctsio->kern_total_len = data_len;
|
||||
} else {
|
||||
ctsio->residual = 0;
|
||||
ctsio->kern_data_len = alloc_len;
|
||||
ctsio->kern_total_len = alloc_len;
|
||||
}
|
||||
|
||||
hdr = (struct scsi_read_toc_hdr *)ctsio->kern_data_ptr;
|
||||
if (format == 0) {
|
||||
scsi_ulto2b(0x12, hdr->data_length);
|
||||
hdr->first = 1;
|
||||
hdr->last = 1;
|
||||
descr = (struct scsi_read_toc_type01_descr *)(hdr + 1);
|
||||
descr->addr_ctl = 0x14;
|
||||
descr->track_number = 1;
|
||||
if (msf)
|
||||
ctl_ultomsf(0, descr->track_start);
|
||||
else
|
||||
scsi_ulto4b(0, descr->track_start);
|
||||
descr++;
|
||||
descr->addr_ctl = 0x14;
|
||||
descr->track_number = 0xaa;
|
||||
if (msf)
|
||||
ctl_ultomsf(lun->be_lun->maxlba+1, descr->track_start);
|
||||
else
|
||||
scsi_ulto4b(lun->be_lun->maxlba+1, descr->track_start);
|
||||
} else {
|
||||
scsi_ulto2b(0x0a, hdr->data_length);
|
||||
hdr->first = 1;
|
||||
hdr->last = 1;
|
||||
descr = (struct scsi_read_toc_type01_descr *)(hdr + 1);
|
||||
descr->addr_ctl = 0x14;
|
||||
descr->track_number = 1;
|
||||
if (msf)
|
||||
ctl_ultomsf(0, descr->track_start);
|
||||
else
|
||||
scsi_ulto4b(0, descr->track_start);
|
||||
}
|
||||
|
||||
ctl_set_success(ctsio);
|
||||
ctsio->io_hdr.flags |= CTL_FLAG_ALLOCATED;
|
||||
ctsio->be_move_done = ctl_config_move_done;
|
||||
ctl_datamove((union ctl_io *)ctsio);
|
||||
return (CTL_RETVAL_COMPLETE);
|
||||
}
|
||||
|
||||
/*
|
||||
* For known CDB types, parse the LBA and length.
|
||||
*/
|
||||
@ -11264,12 +11667,16 @@ ctl_cmd_applicable(uint8_t lun_type, const struct ctl_cmd_entry *entry)
|
||||
{
|
||||
|
||||
switch (lun_type) {
|
||||
case T_DIRECT:
|
||||
if ((entry->flags & CTL_CMD_FLAG_OK_ON_DIRECT) == 0)
|
||||
return (0);
|
||||
break;
|
||||
case T_PROCESSOR:
|
||||
if ((entry->flags & CTL_CMD_FLAG_OK_ON_PROC) == 0)
|
||||
return (0);
|
||||
break;
|
||||
case T_DIRECT:
|
||||
if ((entry->flags & CTL_CMD_FLAG_OK_ON_SLUN) == 0)
|
||||
case T_CDROM:
|
||||
if ((entry->flags & CTL_CMD_FLAG_OK_ON_CDROM) == 0)
|
||||
return (0);
|
||||
break;
|
||||
default:
|
||||
|
@ -1869,6 +1869,8 @@ ctl_be_block_open_file(struct ctl_be_block_lun *be_lun, struct ctl_lun_req *req)
|
||||
*/
|
||||
if (params->blocksize_bytes != 0)
|
||||
cbe_lun->blocksize = params->blocksize_bytes;
|
||||
else if (cbe_lun->lun_type == T_CDROM)
|
||||
cbe_lun->blocksize = 2048;
|
||||
else
|
||||
cbe_lun->blocksize = 512;
|
||||
be_lun->size_blocks = be_lun->size_bytes / cbe_lun->blocksize;
|
||||
@ -1997,7 +1999,9 @@ ctl_be_block_open_dev(struct ctl_be_block_lun *be_lun, struct ctl_lun_req *req)
|
||||
"requested blocksize %u < backing device "
|
||||
"blocksize %u", params->blocksize_bytes, tmp);
|
||||
return (EINVAL);
|
||||
} else
|
||||
} else if (cbe_lun->lun_type == T_CDROM)
|
||||
cbe_lun->blocksize = MAX(tmp, 2048);
|
||||
else
|
||||
cbe_lun->blocksize = tmp;
|
||||
|
||||
error = csw->d_ioctl(dev, DIOCGMEDIASIZE, (caddr_t)&otmp, FREAD,
|
||||
@ -2157,7 +2161,10 @@ ctl_be_block_open(struct ctl_be_block_softc *softc,
|
||||
|
||||
flags = FREAD;
|
||||
value = ctl_get_opt(&cbe_lun->options, "readonly");
|
||||
if (value == NULL || strcmp(value, "on") != 0)
|
||||
if (value != NULL) {
|
||||
if (strcmp(value, "on") != 0)
|
||||
flags |= FWRITE;
|
||||
} else if (cbe_lun->lun_type == T_DIRECT)
|
||||
flags |= FWRITE;
|
||||
|
||||
again:
|
||||
@ -2273,10 +2280,13 @@ ctl_be_block_create(struct ctl_be_block_softc *softc, struct ctl_lun_req *req)
|
||||
} else if (control_softc->flags & CTL_FLAG_ACTIVE_SHELF)
|
||||
cbe_lun->flags |= CTL_LUN_FLAG_PRIMARY;
|
||||
|
||||
if (cbe_lun->lun_type == T_DIRECT) {
|
||||
if (cbe_lun->lun_type == T_DIRECT ||
|
||||
cbe_lun->lun_type == T_CDROM) {
|
||||
be_lun->size_bytes = params->lun_size_bytes;
|
||||
if (params->blocksize_bytes != 0)
|
||||
cbe_lun->blocksize = params->blocksize_bytes;
|
||||
else if (cbe_lun->lun_type == T_CDROM)
|
||||
cbe_lun->blocksize = 2048;
|
||||
else
|
||||
cbe_lun->blocksize = 512;
|
||||
be_lun->size_blocks = be_lun->size_bytes / cbe_lun->blocksize;
|
||||
@ -2761,6 +2771,10 @@ ctl_be_block_config_write(union ctl_io *io)
|
||||
ctl_config_write_done(io);
|
||||
break;
|
||||
}
|
||||
case PREVENT_ALLOW:
|
||||
ctl_set_success(&io->scsiio);
|
||||
ctl_config_write_done(io);
|
||||
break;
|
||||
default:
|
||||
ctl_set_invalid_opcode(&io->scsiio);
|
||||
ctl_config_write_done(io);
|
||||
|
@ -530,9 +530,12 @@ ctl_backend_ramdisk_create(struct ctl_be_ramdisk_softc *softc,
|
||||
} else if (control_softc->flags & CTL_FLAG_ACTIVE_SHELF)
|
||||
cbe_lun->flags |= CTL_LUN_FLAG_PRIMARY;
|
||||
|
||||
if (cbe_lun->lun_type == T_DIRECT) {
|
||||
if (cbe_lun->lun_type == T_DIRECT ||
|
||||
cbe_lun->lun_type == T_CDROM) {
|
||||
if (params->blocksize_bytes != 0)
|
||||
cbe_lun->blocksize = params->blocksize_bytes;
|
||||
else if (cbe_lun->lun_type == T_CDROM)
|
||||
cbe_lun->blocksize = 2048;
|
||||
else
|
||||
cbe_lun->blocksize = 512;
|
||||
if (params->lun_size_bytes < cbe_lun->blocksize) {
|
||||
@ -556,7 +559,10 @@ ctl_backend_ramdisk_create(struct ctl_be_ramdisk_softc *softc,
|
||||
if (value != NULL && strcmp(value, "on") == 0)
|
||||
cbe_lun->flags |= CTL_LUN_FLAG_UNMAP;
|
||||
value = ctl_get_opt(&cbe_lun->options, "readonly");
|
||||
if (value != NULL && strcmp(value, "on") == 0)
|
||||
if (value != NULL) {
|
||||
if (strcmp(value, "on") == 0)
|
||||
cbe_lun->flags |= CTL_LUN_FLAG_READONLY;
|
||||
} else if (cbe_lun->lun_type != T_DIRECT)
|
||||
cbe_lun->flags |= CTL_LUN_FLAG_READONLY;
|
||||
cbe_lun->serseq = CTL_LUN_SERSEQ_OFF;
|
||||
value = ctl_get_opt(&cbe_lun->options, "serseq");
|
||||
@ -896,6 +902,7 @@ ctl_backend_ramdisk_config_write(union ctl_io *io)
|
||||
ctl_config_write_done(io);
|
||||
break;
|
||||
}
|
||||
case PREVENT_ALLOW:
|
||||
case WRITE_SAME_10:
|
||||
case WRITE_SAME_16:
|
||||
case UNMAP:
|
||||
|
@ -255,7 +255,7 @@ const struct ctl_cmd_entry ctl_cmd_table_83[32] =
|
||||
{NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE},
|
||||
|
||||
/* 10 POPULATE TOKEN */
|
||||
{ctl_populate_token, CTL_SERIDX_RD_CAP, CTL_CMD_FLAG_OK_ON_SLUN |
|
||||
{ctl_populate_token, CTL_SERIDX_RD_CAP, CTL_CMD_FLAG_OK_ON_DIRECT |
|
||||
CTL_FLAG_DATA_OUT |
|
||||
CTL_CMD_FLAG_ALLOW_ON_PR_WRESV,
|
||||
CTL_LUN_PAT_NONE,
|
||||
@ -263,7 +263,7 @@ const struct ctl_cmd_entry ctl_cmd_table_83[32] =
|
||||
0xff, 0xff, 0xff, 0xff, 0, 0x07}},
|
||||
|
||||
/* 11 WRITE USING TOKEN */
|
||||
{ctl_write_using_token, CTL_SERIDX_RD_CAP, CTL_CMD_FLAG_OK_ON_SLUN |
|
||||
{ctl_write_using_token, CTL_SERIDX_RD_CAP, CTL_CMD_FLAG_OK_ON_DIRECT |
|
||||
CTL_FLAG_DATA_OUT,
|
||||
CTL_LUN_PAT_NONE,
|
||||
16, { 0x11, 0, 0, 0, 0, 0xff, 0xff, 0xff, 0xff,
|
||||
@ -422,7 +422,7 @@ const struct ctl_cmd_entry ctl_cmd_table_9e[32] =
|
||||
{NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE},
|
||||
|
||||
/* 10 READ CAPACITY(16) */
|
||||
{ctl_read_capacity_16, CTL_SERIDX_RD_CAP, CTL_CMD_FLAG_OK_ON_SLUN |
|
||||
{ctl_read_capacity_16, CTL_SERIDX_RD_CAP, CTL_CMD_FLAG_OK_ON_DIRECT |
|
||||
CTL_CMD_FLAG_OK_ON_STOPPED |
|
||||
CTL_CMD_FLAG_OK_ON_INOPERABLE |
|
||||
CTL_FLAG_DATA_IN |
|
||||
@ -434,7 +434,7 @@ const struct ctl_cmd_entry ctl_cmd_table_9e[32] =
|
||||
{NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE},
|
||||
|
||||
/* 12 GET LBA STATUS */
|
||||
{ctl_get_lba_status, CTL_SERIDX_READ, CTL_CMD_FLAG_OK_ON_SLUN |
|
||||
{ctl_get_lba_status, CTL_SERIDX_READ, CTL_CMD_FLAG_OK_ON_DIRECT |
|
||||
CTL_FLAG_DATA_IN |
|
||||
CTL_CMD_FLAG_ALLOW_ON_PR_WRESV,
|
||||
CTL_LUN_PAT_READ | CTL_LUN_PAT_RANGE,
|
||||
@ -559,7 +559,7 @@ const struct ctl_cmd_entry ctl_cmd_table[256] =
|
||||
CTL_LUN_PAT_NONE, 6, {0x01, 0, 0, 0xff, 0x07}},
|
||||
|
||||
/* 04 FORMAT UNIT */
|
||||
{ctl_format, CTL_SERIDX_FORMAT, CTL_CMD_FLAG_OK_ON_SLUN |
|
||||
{ctl_format, CTL_SERIDX_FORMAT, CTL_CMD_FLAG_OK_ON_DIRECT |
|
||||
CTL_CMD_FLAG_OK_ON_INOPERABLE |
|
||||
CTL_FLAG_DATA_OUT,
|
||||
CTL_LUN_PAT_NONE, 6, {0xff, 0, 0, 0, 0x07}},
|
||||
@ -574,7 +574,7 @@ const struct ctl_cmd_entry ctl_cmd_table[256] =
|
||||
{NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE},
|
||||
|
||||
/* 08 READ(6) */
|
||||
{ctl_read_write, CTL_SERIDX_READ, CTL_CMD_FLAG_OK_ON_SLUN |
|
||||
{ctl_read_write, CTL_SERIDX_READ, CTL_CMD_FLAG_OK_ON_DIRECT |
|
||||
CTL_FLAG_DATA_IN |
|
||||
CTL_CMD_FLAG_ALLOW_ON_PR_WRESV,
|
||||
CTL_LUN_PAT_READ | CTL_LUN_PAT_RANGE, 6, {0x1f, 0xff, 0xff, 0xff, 0x07}},
|
||||
@ -583,7 +583,7 @@ const struct ctl_cmd_entry ctl_cmd_table[256] =
|
||||
{NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE},
|
||||
|
||||
/* 0A WRITE(6) */
|
||||
{ctl_read_write, CTL_SERIDX_WRITE, CTL_CMD_FLAG_OK_ON_SLUN |
|
||||
{ctl_read_write, CTL_SERIDX_WRITE, CTL_CMD_FLAG_OK_ON_DIRECT |
|
||||
CTL_FLAG_DATA_OUT,
|
||||
CTL_LUN_PAT_WRITE | CTL_LUN_PAT_RANGE, 6, {0x1f, 0xff, 0xff, 0xff, 0x07}},
|
||||
|
||||
@ -669,7 +669,8 @@ const struct ctl_cmd_entry ctl_cmd_table[256] =
|
||||
CTL_LUN_PAT_NONE, 6, {0x08, 0xff, 0xff, 0xff, 0x07}},
|
||||
|
||||
/* 1B START STOP UNIT */
|
||||
{ctl_start_stop, CTL_SERIDX_START, CTL_CMD_FLAG_OK_ON_SLUN |
|
||||
{ctl_start_stop, CTL_SERIDX_START, CTL_CMD_FLAG_OK_ON_DIRECT |
|
||||
CTL_CMD_FLAG_OK_ON_CDROM |
|
||||
CTL_CMD_FLAG_OK_ON_STOPPED |
|
||||
CTL_CMD_FLAG_OK_ON_INOPERABLE |
|
||||
CTL_FLAG_DATA_NONE |
|
||||
@ -683,7 +684,12 @@ const struct ctl_cmd_entry ctl_cmd_table[256] =
|
||||
{NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE},
|
||||
|
||||
/* 1E PREVENT ALLOW MEDIUM REMOVAL */
|
||||
{NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE},
|
||||
{ctl_prevent_allow, CTL_SERIDX_START, CTL_CMD_FLAG_OK_ON_DIRECT |
|
||||
CTL_CMD_FLAG_OK_ON_CDROM |
|
||||
CTL_CMD_FLAG_OK_ON_STOPPED |
|
||||
CTL_CMD_FLAG_OK_ON_INOPERABLE |
|
||||
CTL_FLAG_DATA_NONE,
|
||||
CTL_LUN_PAT_NONE, 6, {0x01, 0, 0, 0x03, 0x07}},
|
||||
|
||||
/* 1F */
|
||||
{NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE},
|
||||
@ -704,7 +710,8 @@ const struct ctl_cmd_entry ctl_cmd_table[256] =
|
||||
{NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE},
|
||||
|
||||
/* 25 READ CAPACITY(10) */
|
||||
{ctl_read_capacity, CTL_SERIDX_RD_CAP, CTL_CMD_FLAG_OK_ON_SLUN|
|
||||
{ctl_read_capacity, CTL_SERIDX_RD_CAP, CTL_CMD_FLAG_OK_ON_DIRECT |
|
||||
CTL_CMD_FLAG_OK_ON_CDROM |
|
||||
CTL_CMD_FLAG_OK_ON_STOPPED |
|
||||
CTL_CMD_FLAG_OK_ON_INOPERABLE |
|
||||
CTL_FLAG_DATA_IN |
|
||||
@ -718,7 +725,8 @@ const struct ctl_cmd_entry ctl_cmd_table[256] =
|
||||
{NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE},
|
||||
|
||||
/* 28 READ(10) */
|
||||
{ctl_read_write, CTL_SERIDX_READ, CTL_CMD_FLAG_OK_ON_SLUN |
|
||||
{ctl_read_write, CTL_SERIDX_READ, CTL_CMD_FLAG_OK_ON_DIRECT |
|
||||
CTL_CMD_FLAG_OK_ON_CDROM |
|
||||
CTL_FLAG_DATA_IN |
|
||||
CTL_CMD_FLAG_ALLOW_ON_PR_WRESV,
|
||||
CTL_LUN_PAT_READ | CTL_LUN_PAT_RANGE,
|
||||
@ -728,7 +736,7 @@ const struct ctl_cmd_entry ctl_cmd_table[256] =
|
||||
{NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE},
|
||||
|
||||
/* 2A WRITE(10) */
|
||||
{ctl_read_write, CTL_SERIDX_WRITE, CTL_CMD_FLAG_OK_ON_SLUN| CTL_FLAG_DATA_OUT,
|
||||
{ctl_read_write, CTL_SERIDX_WRITE, CTL_CMD_FLAG_OK_ON_DIRECT| CTL_FLAG_DATA_OUT,
|
||||
CTL_LUN_PAT_WRITE | CTL_LUN_PAT_RANGE,
|
||||
10, {0x1a, 0xff, 0xff, 0xff, 0xff, 0, 0xff, 0xff, 0x07}},
|
||||
|
||||
@ -742,12 +750,12 @@ const struct ctl_cmd_entry ctl_cmd_table[256] =
|
||||
{NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE},
|
||||
|
||||
/* 2E WRITE AND VERIFY(10) */
|
||||
{ctl_read_write, CTL_SERIDX_WRITE, CTL_CMD_FLAG_OK_ON_SLUN| CTL_FLAG_DATA_OUT,
|
||||
{ctl_read_write, CTL_SERIDX_WRITE, CTL_CMD_FLAG_OK_ON_DIRECT| CTL_FLAG_DATA_OUT,
|
||||
CTL_LUN_PAT_WRITE | CTL_LUN_PAT_RANGE,
|
||||
10, {0x12, 0xff, 0xff, 0xff, 0xff, 0, 0xff, 0xff, 0x07}},
|
||||
|
||||
/* 2F VERIFY(10) */
|
||||
{ctl_verify, CTL_SERIDX_READ, CTL_CMD_FLAG_OK_ON_SLUN |
|
||||
{ctl_verify, CTL_SERIDX_READ, CTL_CMD_FLAG_OK_ON_DIRECT |
|
||||
CTL_FLAG_DATA_OUT |
|
||||
CTL_CMD_FLAG_ALLOW_ON_PR_WRESV,
|
||||
CTL_LUN_PAT_READ | CTL_LUN_PAT_RANGE,
|
||||
@ -769,7 +777,7 @@ const struct ctl_cmd_entry ctl_cmd_table[256] =
|
||||
{NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE},
|
||||
|
||||
/* 35 SYNCHRONIZE CACHE(10) */
|
||||
{ctl_sync_cache, CTL_SERIDX_SYNC, CTL_CMD_FLAG_OK_ON_SLUN |
|
||||
{ctl_sync_cache, CTL_SERIDX_SYNC, CTL_CMD_FLAG_OK_ON_DIRECT |
|
||||
CTL_FLAG_DATA_NONE,
|
||||
CTL_LUN_PAT_WRITE,
|
||||
10, {0x02, 0xff, 0xff, 0xff, 0xff, 0, 0xff, 0xff, 0x07}},
|
||||
@ -778,7 +786,7 @@ const struct ctl_cmd_entry ctl_cmd_table[256] =
|
||||
{NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE},
|
||||
|
||||
/* 37 READ DEFECT DATA(10) */
|
||||
{ctl_read_defect, CTL_SERIDX_MD_SNS, CTL_CMD_FLAG_OK_ON_SLUN |
|
||||
{ctl_read_defect, CTL_SERIDX_MD_SNS, CTL_CMD_FLAG_OK_ON_DIRECT |
|
||||
CTL_FLAG_DATA_IN |
|
||||
CTL_CMD_FLAG_ALLOW_ON_PR_WRESV,
|
||||
CTL_LUN_PAT_NONE,
|
||||
@ -825,18 +833,22 @@ const struct ctl_cmd_entry ctl_cmd_table[256] =
|
||||
{NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE},
|
||||
|
||||
/* 41 WRITE SAME(10) */
|
||||
{ctl_write_same, CTL_SERIDX_WRITE, CTL_CMD_FLAG_OK_ON_SLUN |
|
||||
{ctl_write_same, CTL_SERIDX_WRITE, CTL_CMD_FLAG_OK_ON_DIRECT |
|
||||
CTL_FLAG_DATA_OUT,
|
||||
CTL_LUN_PAT_WRITE | CTL_LUN_PAT_RANGE,
|
||||
10, {0x1a, 0xff, 0xff, 0xff, 0xff, 0, 0xff, 0xff, 0x07}},
|
||||
|
||||
/* 42 READ SUB-CHANNEL / UNMAP */
|
||||
{ctl_unmap, CTL_SERIDX_UNMAP, CTL_CMD_FLAG_OK_ON_SLUN | CTL_FLAG_DATA_OUT,
|
||||
{ctl_unmap, CTL_SERIDX_UNMAP, CTL_CMD_FLAG_OK_ON_DIRECT | CTL_FLAG_DATA_OUT,
|
||||
CTL_LUN_PAT_WRITE,
|
||||
10, {1, 0, 0, 0, 0, 0, 0xff, 0xff, 0x07}},
|
||||
|
||||
/* 43 READ TOC/PMA/ATIP */
|
||||
{NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE},
|
||||
{ctl_read_toc, CTL_SERIDX_RD_CAP, CTL_CMD_FLAG_OK_ON_CDROM |
|
||||
CTL_CMD_FLAG_ALLOW_ON_PR_WRESV |
|
||||
CTL_FLAG_DATA_IN,
|
||||
CTL_LUN_PAT_NONE,
|
||||
10, {0x02, 0x01, 0, 0, 0, 0xff, 0xff, 0xff, 0x07}},
|
||||
|
||||
/* 44 REPORT DENSITY SUPPORT */
|
||||
{NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE},
|
||||
@ -845,7 +857,12 @@ const struct ctl_cmd_entry ctl_cmd_table[256] =
|
||||
{NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE},
|
||||
|
||||
/* 46 GET CONFIGURATION */
|
||||
{NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE},
|
||||
{ctl_get_config, CTL_SERIDX_INQ, CTL_CMD_FLAG_OK_ON_CDROM |
|
||||
CTL_CMD_FLAG_OK_ON_STOPPED |
|
||||
CTL_CMD_FLAG_ALLOW_ON_PR_RESV |
|
||||
CTL_FLAG_DATA_IN,
|
||||
CTL_LUN_PAT_NONE,
|
||||
10, {0x03, 0xff, 0xff, 0, 0, 0, 0xff, 0xff, 0x07}},
|
||||
|
||||
/* 47 PLAY AUDIO MSF */
|
||||
{NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE},
|
||||
@ -857,7 +874,13 @@ const struct ctl_cmd_entry ctl_cmd_table[256] =
|
||||
{NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE},
|
||||
|
||||
/* 4A GET EVENT STATUS NOTIFICATION */
|
||||
{NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE},
|
||||
{ctl_get_event_status, CTL_SERIDX_RD_CAP, CTL_CMD_FLAG_OK_ON_CDROM |
|
||||
CTL_CMD_FLAG_OK_ON_STOPPED |
|
||||
CTL_CMD_FLAG_OK_ON_INOPERABLE |
|
||||
CTL_CMD_FLAG_ALLOW_ON_PR_RESV |
|
||||
CTL_FLAG_DATA_IN,
|
||||
CTL_LUN_PAT_NONE,
|
||||
10, {0x02, 0x01, 0, 0, 0, 0xff, 0xff, 0xff, 0x07}},
|
||||
|
||||
/* 4B PAUSE/RESUME */
|
||||
{NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE},
|
||||
@ -1076,20 +1099,20 @@ const struct ctl_cmd_entry ctl_cmd_table[256] =
|
||||
{NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE},
|
||||
|
||||
/* 88 READ(16) */
|
||||
{ctl_read_write, CTL_SERIDX_READ, CTL_CMD_FLAG_OK_ON_SLUN | CTL_FLAG_DATA_IN |
|
||||
{ctl_read_write, CTL_SERIDX_READ, CTL_CMD_FLAG_OK_ON_DIRECT | CTL_FLAG_DATA_IN |
|
||||
CTL_CMD_FLAG_ALLOW_ON_PR_WRESV,
|
||||
CTL_LUN_PAT_READ | CTL_LUN_PAT_RANGE,
|
||||
16, {0x1a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0x07}},
|
||||
|
||||
/* 89 COMPARE AND WRITE */
|
||||
{ctl_cnw, CTL_SERIDX_WRITE, CTL_CMD_FLAG_OK_ON_SLUN| CTL_FLAG_DATA_OUT,
|
||||
{ctl_cnw, CTL_SERIDX_WRITE, CTL_CMD_FLAG_OK_ON_DIRECT| CTL_FLAG_DATA_OUT,
|
||||
CTL_LUN_PAT_WRITE | CTL_LUN_PAT_RANGE,
|
||||
16, {0x18, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0, 0, 0, 0xff, 0, 0x07}},
|
||||
|
||||
/* 8A WRITE(16) */
|
||||
{ctl_read_write, CTL_SERIDX_WRITE, CTL_CMD_FLAG_OK_ON_SLUN| CTL_FLAG_DATA_OUT,
|
||||
{ctl_read_write, CTL_SERIDX_WRITE, CTL_CMD_FLAG_OK_ON_DIRECT| CTL_FLAG_DATA_OUT,
|
||||
CTL_LUN_PAT_WRITE | CTL_LUN_PAT_RANGE,
|
||||
16, {0x1a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0x07}},
|
||||
@ -1104,13 +1127,13 @@ const struct ctl_cmd_entry ctl_cmd_table[256] =
|
||||
{NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE},
|
||||
|
||||
/* 8E WRITE AND VERIFY(16) */
|
||||
{ctl_read_write, CTL_SERIDX_WRITE, CTL_CMD_FLAG_OK_ON_SLUN| CTL_FLAG_DATA_OUT,
|
||||
{ctl_read_write, CTL_SERIDX_WRITE, CTL_CMD_FLAG_OK_ON_DIRECT| CTL_FLAG_DATA_OUT,
|
||||
CTL_LUN_PAT_WRITE | CTL_LUN_PAT_RANGE,
|
||||
16, {0x12, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0x07}},
|
||||
|
||||
/* 8F VERIFY(16) */
|
||||
{ctl_verify, CTL_SERIDX_READ, CTL_CMD_FLAG_OK_ON_SLUN |
|
||||
{ctl_verify, CTL_SERIDX_READ, CTL_CMD_FLAG_OK_ON_DIRECT |
|
||||
CTL_FLAG_DATA_OUT |
|
||||
CTL_CMD_FLAG_ALLOW_ON_PR_WRESV,
|
||||
CTL_LUN_PAT_READ | CTL_LUN_PAT_RANGE,
|
||||
@ -1121,7 +1144,7 @@ const struct ctl_cmd_entry ctl_cmd_table[256] =
|
||||
{NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE},
|
||||
|
||||
/* 91 SYNCHRONIZE CACHE(16) */
|
||||
{ctl_sync_cache, CTL_SERIDX_SYNC, CTL_CMD_FLAG_OK_ON_SLUN |
|
||||
{ctl_sync_cache, CTL_SERIDX_SYNC, CTL_CMD_FLAG_OK_ON_DIRECT |
|
||||
CTL_FLAG_DATA_NONE,
|
||||
CTL_LUN_PAT_WRITE,
|
||||
16, {0x02, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
@ -1131,7 +1154,7 @@ const struct ctl_cmd_entry ctl_cmd_table[256] =
|
||||
{NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE},
|
||||
|
||||
/* 93 WRITE SAME(16) */
|
||||
{ctl_write_same, CTL_SERIDX_WRITE, CTL_CMD_FLAG_OK_ON_SLUN |
|
||||
{ctl_write_same, CTL_SERIDX_WRITE, CTL_CMD_FLAG_OK_ON_DIRECT |
|
||||
CTL_FLAG_DATA_OUT,
|
||||
CTL_LUN_PAT_WRITE | CTL_LUN_PAT_RANGE,
|
||||
16, {0x1b, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
@ -1170,7 +1193,7 @@ const struct ctl_cmd_entry ctl_cmd_table[256] =
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0x07}},
|
||||
|
||||
/* 9C WRITE ATOMIC (16) */
|
||||
{ctl_read_write, CTL_SERIDX_WRITE, CTL_CMD_FLAG_OK_ON_SLUN| CTL_FLAG_DATA_OUT,
|
||||
{ctl_read_write, CTL_SERIDX_WRITE, CTL_CMD_FLAG_OK_ON_DIRECT| CTL_FLAG_DATA_OUT,
|
||||
CTL_LUN_PAT_WRITE | CTL_LUN_PAT_RANGE,
|
||||
16, {0x18, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0, 0, 0xff, 0xff, 0, 0x07}},
|
||||
@ -1223,8 +1246,10 @@ const struct ctl_cmd_entry ctl_cmd_table[256] =
|
||||
{NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE},
|
||||
|
||||
/* A8 READ(12) */
|
||||
{ctl_read_write, CTL_SERIDX_READ, CTL_CMD_FLAG_OK_ON_SLUN | CTL_FLAG_DATA_IN |
|
||||
CTL_CMD_FLAG_ALLOW_ON_PR_WRESV,
|
||||
{ctl_read_write, CTL_SERIDX_READ, CTL_CMD_FLAG_OK_ON_DIRECT |
|
||||
CTL_CMD_FLAG_OK_ON_CDROM |
|
||||
CTL_FLAG_DATA_IN |
|
||||
CTL_CMD_FLAG_ALLOW_ON_PR_WRESV,
|
||||
CTL_LUN_PAT_READ | CTL_LUN_PAT_RANGE,
|
||||
12, {0x1a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0x07}},
|
||||
|
||||
@ -1232,7 +1257,7 @@ const struct ctl_cmd_entry ctl_cmd_table[256] =
|
||||
{NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE},
|
||||
|
||||
/* AA WRITE(12) */
|
||||
{ctl_read_write, CTL_SERIDX_WRITE, CTL_CMD_FLAG_OK_ON_SLUN| CTL_FLAG_DATA_OUT,
|
||||
{ctl_read_write, CTL_SERIDX_WRITE, CTL_CMD_FLAG_OK_ON_DIRECT| CTL_FLAG_DATA_OUT,
|
||||
CTL_LUN_PAT_WRITE | CTL_LUN_PAT_RANGE,
|
||||
12, {0x1a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0x07}},
|
||||
|
||||
@ -1246,12 +1271,12 @@ const struct ctl_cmd_entry ctl_cmd_table[256] =
|
||||
{NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE},
|
||||
|
||||
/* AE WRITE AND VERIFY(12) */
|
||||
{ctl_read_write, CTL_SERIDX_WRITE, CTL_CMD_FLAG_OK_ON_SLUN| CTL_FLAG_DATA_OUT,
|
||||
{ctl_read_write, CTL_SERIDX_WRITE, CTL_CMD_FLAG_OK_ON_DIRECT| CTL_FLAG_DATA_OUT,
|
||||
CTL_LUN_PAT_WRITE | CTL_LUN_PAT_RANGE,
|
||||
12, {0x12, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0x07}},
|
||||
|
||||
/* AF VERIFY(12) */
|
||||
{ctl_verify, CTL_SERIDX_READ, CTL_CMD_FLAG_OK_ON_SLUN |
|
||||
{ctl_verify, CTL_SERIDX_READ, CTL_CMD_FLAG_OK_ON_DIRECT |
|
||||
CTL_FLAG_DATA_OUT |
|
||||
CTL_CMD_FLAG_ALLOW_ON_PR_WRESV,
|
||||
CTL_LUN_PAT_READ | CTL_LUN_PAT_RANGE,
|
||||
@ -1279,7 +1304,7 @@ const struct ctl_cmd_entry ctl_cmd_table[256] =
|
||||
{NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE},
|
||||
|
||||
/* B7 READ DEFECT DATA(12) */
|
||||
{ctl_read_defect, CTL_SERIDX_MD_SNS, CTL_CMD_FLAG_OK_ON_SLUN |
|
||||
{ctl_read_defect, CTL_SERIDX_MD_SNS, CTL_CMD_FLAG_OK_ON_DIRECT |
|
||||
CTL_FLAG_DATA_IN |
|
||||
CTL_CMD_FLAG_ALLOW_ON_PR_WRESV,
|
||||
CTL_LUN_PAT_NONE,
|
||||
@ -1300,8 +1325,14 @@ const struct ctl_cmd_entry ctl_cmd_table[256] =
|
||||
/* BC SPARE IN */
|
||||
{NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE},
|
||||
|
||||
/* BD SPARE OUT */
|
||||
{NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE},
|
||||
/* BD SPARE OUT / MECHANISM STATUS */
|
||||
{ctl_mechanism_status, CTL_SERIDX_RD_CAP, CTL_CMD_FLAG_OK_ON_CDROM |
|
||||
CTL_CMD_FLAG_OK_ON_STOPPED |
|
||||
CTL_CMD_FLAG_OK_ON_INOPERABLE |
|
||||
CTL_CMD_FLAG_ALLOW_ON_PR_RESV |
|
||||
CTL_FLAG_DATA_IN,
|
||||
CTL_LUN_PAT_NONE,
|
||||
12, {0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 0, 0x07}},
|
||||
|
||||
/* BE VOLUME SET IN */
|
||||
{NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE},
|
||||
|
@ -45,6 +45,7 @@
|
||||
#define CTL_VENDOR "FREEBSD "
|
||||
#define CTL_DIRECT_PRODUCT "CTLDISK "
|
||||
#define CTL_PROCESSOR_PRODUCT "CTLPROCESSOR "
|
||||
#define CTL_CDROM_PRODUCT "CTLCDROM "
|
||||
#define CTL_UNKNOWN_PRODUCT "CTLDEVICE "
|
||||
|
||||
#define CTL_POOL_ENTRIES_OTHER_SC 200
|
||||
@ -90,15 +91,16 @@ typedef enum {
|
||||
CTL_CMD_FLAG_ALLOW_ON_RESV = 0x0040,
|
||||
CTL_CMD_FLAG_ALLOW_ON_PR_WRESV = 0x0080,
|
||||
CTL_CMD_FLAG_OK_ON_PROC = 0x0100,
|
||||
CTL_CMD_FLAG_OK_ON_SLUN = 0x0200,
|
||||
CTL_CMD_FLAG_OK_ON_BOTH = 0x0300,
|
||||
CTL_CMD_FLAG_OK_ON_STOPPED = 0x0400,
|
||||
CTL_CMD_FLAG_OK_ON_DIRECT = 0x0200,
|
||||
CTL_CMD_FLAG_OK_ON_CDROM = 0x0400,
|
||||
CTL_CMD_FLAG_OK_ON_BOTH = 0x0700,
|
||||
CTL_CMD_FLAG_OK_ON_INOPERABLE = 0x0800,
|
||||
CTL_CMD_FLAG_OK_ON_STANDBY = 0x1000,
|
||||
CTL_CMD_FLAG_OK_ON_UNAVAIL = 0x2000,
|
||||
CTL_CMD_FLAG_ALLOW_ON_PR_RESV = 0x4000,
|
||||
CTL_CMD_FLAG_SA5 = 0x8000,
|
||||
CTL_CMD_FLAG_RUN_HERE = 0x10000
|
||||
CTL_CMD_FLAG_RUN_HERE = 0x10000,
|
||||
CTL_CMD_FLAG_OK_ON_STOPPED = 0x20000
|
||||
} ctl_cmd_flags;
|
||||
|
||||
typedef enum {
|
||||
@ -147,7 +149,8 @@ typedef enum {
|
||||
CTL_LUN_PRIMARY_SC = 0x200,
|
||||
CTL_LUN_SENSE_DESC = 0x400,
|
||||
CTL_LUN_READONLY = 0x800,
|
||||
CTL_LUN_PEER_SC_PRIMARY = 0x1000
|
||||
CTL_LUN_PEER_SC_PRIMARY = 0x1000,
|
||||
CTL_LUN_REMOVABLE = 0x2000
|
||||
} ctl_lun_flags;
|
||||
|
||||
typedef enum {
|
||||
@ -231,7 +234,10 @@ typedef int ctl_modesel_handler(struct ctl_scsiio *ctsio,
|
||||
|
||||
typedef enum {
|
||||
CTL_PAGE_FLAG_NONE = 0x00,
|
||||
CTL_PAGE_FLAG_DISK_ONLY = 0x01
|
||||
CTL_PAGE_FLAG_DIRECT = 0x01,
|
||||
CTL_PAGE_FLAG_PROC = 0x02,
|
||||
CTL_PAGE_FLAG_CDROM = 0x04,
|
||||
CTL_PAGE_FLAG_ALL = 0x07
|
||||
} ctl_page_flags;
|
||||
|
||||
struct ctl_page_index {
|
||||
@ -262,25 +268,26 @@ struct ctl_logical_block_provisioning_page {
|
||||
|
||||
static const struct ctl_page_index page_index_template[] = {
|
||||
{SMS_RW_ERROR_RECOVERY_PAGE, 0, sizeof(struct scsi_da_rw_recovery_page), NULL,
|
||||
CTL_PAGE_FLAG_DISK_ONLY, NULL, NULL},
|
||||
CTL_PAGE_FLAG_DIRECT | CTL_PAGE_FLAG_CDROM, NULL, NULL},
|
||||
{SMS_FORMAT_DEVICE_PAGE, 0, sizeof(struct scsi_format_page), NULL,
|
||||
CTL_PAGE_FLAG_DISK_ONLY, NULL, NULL},
|
||||
CTL_PAGE_FLAG_DIRECT, NULL, NULL},
|
||||
{SMS_RIGID_DISK_PAGE, 0, sizeof(struct scsi_rigid_disk_page), NULL,
|
||||
CTL_PAGE_FLAG_DISK_ONLY, NULL, NULL},
|
||||
CTL_PAGE_FLAG_DIRECT, NULL, NULL},
|
||||
{SMS_CACHING_PAGE, 0, sizeof(struct scsi_caching_page), NULL,
|
||||
CTL_PAGE_FLAG_DISK_ONLY, NULL, ctl_caching_sp_handler},
|
||||
CTL_PAGE_FLAG_DIRECT | CTL_PAGE_FLAG_CDROM,
|
||||
NULL, ctl_caching_sp_handler},
|
||||
{SMS_CONTROL_MODE_PAGE, 0, sizeof(struct scsi_control_page), NULL,
|
||||
CTL_PAGE_FLAG_NONE, NULL, ctl_control_page_handler},
|
||||
CTL_PAGE_FLAG_ALL, NULL, ctl_control_page_handler},
|
||||
{SMS_CONTROL_MODE_PAGE | SMPH_SPF, 0x01,
|
||||
sizeof(struct scsi_control_ext_page), NULL,
|
||||
CTL_PAGE_FLAG_NONE, NULL, NULL},
|
||||
CTL_PAGE_FLAG_ALL, NULL, NULL},
|
||||
{SMS_INFO_EXCEPTIONS_PAGE, 0, sizeof(struct scsi_info_exceptions_page), NULL,
|
||||
CTL_PAGE_FLAG_NONE, NULL, NULL},
|
||||
CTL_PAGE_FLAG_ALL, NULL, NULL},
|
||||
{SMS_INFO_EXCEPTIONS_PAGE | SMPH_SPF, 0x02,
|
||||
sizeof(struct ctl_logical_block_provisioning_page), NULL,
|
||||
CTL_PAGE_FLAG_DISK_ONLY, NULL, NULL},
|
||||
CTL_PAGE_FLAG_DIRECT, NULL, NULL},
|
||||
{SMS_VENDOR_SPECIFIC_PAGE | SMPH_SPF, DBGCNF_SUBPAGE_CODE,
|
||||
sizeof(struct copan_debugconf_subpage), NULL, CTL_PAGE_FLAG_NONE,
|
||||
sizeof(struct copan_debugconf_subpage), NULL, CTL_PAGE_FLAG_ALL,
|
||||
ctl_debugconf_sp_sense_handler, ctl_debugconf_sp_select_handler},
|
||||
};
|
||||
|
||||
@ -302,13 +309,13 @@ struct ctl_mode_pages {
|
||||
|
||||
static const struct ctl_page_index log_page_index_template[] = {
|
||||
{SLS_SUPPORTED_PAGES_PAGE, 0, 0, NULL,
|
||||
CTL_PAGE_FLAG_NONE, NULL, NULL},
|
||||
CTL_PAGE_FLAG_ALL, NULL, NULL},
|
||||
{SLS_SUPPORTED_PAGES_PAGE, SLS_SUPPORTED_SUBPAGES_SUBPAGE, 0, NULL,
|
||||
CTL_PAGE_FLAG_NONE, NULL, NULL},
|
||||
CTL_PAGE_FLAG_ALL, NULL, NULL},
|
||||
{SLS_LOGICAL_BLOCK_PROVISIONING, 0, 0, NULL,
|
||||
CTL_PAGE_FLAG_DISK_ONLY, ctl_lbp_log_sense_handler, NULL},
|
||||
CTL_PAGE_FLAG_DIRECT, ctl_lbp_log_sense_handler, NULL},
|
||||
{SLS_STAT_AND_PERF, 0, 0, NULL,
|
||||
CTL_PAGE_FLAG_NONE, ctl_sap_log_sense_handler, NULL},
|
||||
CTL_PAGE_FLAG_ALL, ctl_sap_log_sense_handler, NULL},
|
||||
};
|
||||
|
||||
#define CTL_NUM_LOG_PAGES sizeof(log_page_index_template)/ \
|
||||
@ -459,6 +466,7 @@ void ctl_pool_free(struct ctl_io_pool *pool);
|
||||
int ctl_scsi_release(struct ctl_scsiio *ctsio);
|
||||
int ctl_scsi_reserve(struct ctl_scsiio *ctsio);
|
||||
int ctl_start_stop(struct ctl_scsiio *ctsio);
|
||||
int ctl_prevent_allow(struct ctl_scsiio *ctsio);
|
||||
int ctl_sync_cache(struct ctl_scsiio *ctsio);
|
||||
int ctl_format(struct ctl_scsiio *ctsio);
|
||||
int ctl_read_buffer(struct ctl_scsiio *ctsio);
|
||||
@ -471,6 +479,7 @@ int ctl_log_sense(struct ctl_scsiio *ctsio);
|
||||
int ctl_read_capacity(struct ctl_scsiio *ctsio);
|
||||
int ctl_read_capacity_16(struct ctl_scsiio *ctsio);
|
||||
int ctl_read_defect(struct ctl_scsiio *ctsio);
|
||||
int ctl_read_toc(struct ctl_scsiio *ctsio);
|
||||
int ctl_read_write(struct ctl_scsiio *ctsio);
|
||||
int ctl_cnw(struct ctl_scsiio *ctsio);
|
||||
int ctl_report_luns(struct ctl_scsiio *ctsio);
|
||||
@ -478,6 +487,9 @@ int ctl_request_sense(struct ctl_scsiio *ctsio);
|
||||
int ctl_tur(struct ctl_scsiio *ctsio);
|
||||
int ctl_verify(struct ctl_scsiio *ctsio);
|
||||
int ctl_inquiry(struct ctl_scsiio *ctsio);
|
||||
int ctl_get_config(struct ctl_scsiio *ctsio);
|
||||
int ctl_get_event_status(struct ctl_scsiio *ctsio);
|
||||
int ctl_mechanism_status(struct ctl_scsiio *ctsio);
|
||||
int ctl_persistent_reserve_in(struct ctl_scsiio *ctsio);
|
||||
int ctl_persistent_reserve_out(struct ctl_scsiio *ctsio);
|
||||
int ctl_report_tagret_port_groups(struct ctl_scsiio *ctsio);
|
||||
|
@ -56,6 +56,83 @@
|
||||
* SCSI command format
|
||||
*/
|
||||
|
||||
struct scsi_get_config
|
||||
{
|
||||
uint8_t opcode;
|
||||
uint8_t rt;
|
||||
#define SGC_RT_ALL 0x00
|
||||
#define SGC_RT_CURRENT 0x01
|
||||
#define SGC_RT_SPECIFIC 0x02
|
||||
#define SGC_RT_MASK 0x03
|
||||
uint8_t starting_feature[2];
|
||||
uint8_t reserved[3];
|
||||
uint8_t length[2];
|
||||
uint8_t control;
|
||||
};
|
||||
|
||||
struct scsi_get_config_header
|
||||
{
|
||||
uint8_t data_length[4];
|
||||
uint8_t reserved[2];
|
||||
uint8_t current_profile[2];
|
||||
};
|
||||
|
||||
struct scsi_get_config_feature
|
||||
{
|
||||
uint8_t feature_code[2];
|
||||
uint8_t flags;
|
||||
#define SGC_F_CURRENT 0x01
|
||||
#define SGC_F_PERSISTENT 0x02
|
||||
#define SGC_F_VERSION_MASK 0x2C
|
||||
#define SGC_F_VERSION_SHIFT 2
|
||||
uint8_t add_length;
|
||||
uint8_t feature_data[];
|
||||
};
|
||||
|
||||
struct scsi_get_event_status
|
||||
{
|
||||
uint8_t opcode;
|
||||
uint8_t byte2;
|
||||
#define SGESN_POLLED 1
|
||||
uint8_t reserved[2];
|
||||
uint8_t notif_class;
|
||||
uint8_t reserved2[2];
|
||||
uint8_t length[2];
|
||||
uint8_t control;
|
||||
};
|
||||
|
||||
struct scsi_get_event_status_header
|
||||
{
|
||||
uint8_t descr_length[4];
|
||||
uint8_t nea_class;
|
||||
#define SGESN_NEA 0x80
|
||||
uint8_t supported_class;
|
||||
};
|
||||
|
||||
struct scsi_get_event_status_descr
|
||||
{
|
||||
uint8_t event_code;
|
||||
uint8_t event_info[];
|
||||
};
|
||||
|
||||
struct scsi_mechanism_status
|
||||
{
|
||||
uint8_t opcode;
|
||||
uint8_t reserved[7];
|
||||
uint8_t length[2];
|
||||
uint8_t reserved2;
|
||||
uint8_t control;
|
||||
};
|
||||
|
||||
struct scsi_mechanism_status_header
|
||||
{
|
||||
uint8_t state1;
|
||||
uint8_t state2;
|
||||
uint8_t lba[3];
|
||||
uint8_t slots_num;
|
||||
uint8_t slots_length[2];
|
||||
};
|
||||
|
||||
struct scsi_pause
|
||||
{
|
||||
u_int8_t op_code;
|
||||
@ -151,12 +228,29 @@ struct scsi_read_toc
|
||||
{
|
||||
u_int8_t op_code;
|
||||
u_int8_t byte2;
|
||||
u_int8_t unused[4];
|
||||
u_int8_t format;
|
||||
u_int8_t unused[3];
|
||||
u_int8_t from_track;
|
||||
u_int8_t data_len[2];
|
||||
u_int8_t control;
|
||||
};
|
||||
|
||||
struct scsi_read_toc_hdr
|
||||
{
|
||||
uint8_t data_length[2];
|
||||
uint8_t first;
|
||||
uint8_t last;
|
||||
};
|
||||
|
||||
struct scsi_read_toc_type01_descr
|
||||
{
|
||||
uint8_t reserved;
|
||||
uint8_t addr_ctl;
|
||||
uint8_t track_number;
|
||||
uint8_t reserved2;
|
||||
uint8_t track_start[4];
|
||||
};
|
||||
|
||||
struct scsi_read_cd_capacity
|
||||
{
|
||||
u_int8_t op_code;
|
||||
@ -252,9 +346,11 @@ struct scsi_read_dvd_structure
|
||||
#define READ_TOC 0x43 /* cdrom read TOC */
|
||||
#define READ_HEADER 0x44 /* cdrom read header */
|
||||
#define PLAY_10 0x45 /* cdrom play 'play audio' mode */
|
||||
#define GET_CONFIGURATION 0x46 /* Get device configuration */
|
||||
#define PLAY_MSF 0x47 /* cdrom play Min,Sec,Frames mode */
|
||||
#define PLAY_TRACK 0x48 /* cdrom play track/index mode */
|
||||
#define PLAY_TRACK_REL 0x49 /* cdrom play track/index mode */
|
||||
#define GET_EVENT_STATUS 0x4a /* Get event status notification */
|
||||
#define PAUSE 0x4b /* cdrom pause in 'play audio' mode */
|
||||
#define SEND_KEY 0xa3 /* dvd send key command */
|
||||
#define REPORT_KEY 0xa4 /* dvd report key command */
|
||||
@ -262,6 +358,7 @@ struct scsi_read_dvd_structure
|
||||
#define PLAY_TRACK_REL_BIG 0xa9 /* cdrom play track/index mode */
|
||||
#define READ_DVD_STRUCTURE 0xad /* read dvd structure */
|
||||
#define SET_CD_SPEED 0xbb /* set c/dvd speed */
|
||||
#define MECHANISM_STATUS 0xbd /* get status of c/dvd mechanics */
|
||||
|
||||
struct scsi_report_key_data_header
|
||||
{
|
||||
|
@ -717,11 +717,10 @@ Specify the serial number to be used in the
|
||||
INQUIRY VPD page 0x80 data.
|
||||
.It Fl t Ar device_type
|
||||
Specify the numeric SCSI device type to use when creating the LUN.
|
||||
For example, the Direct Access type is 0.
|
||||
If this flag is not used, the type of LUN created is backend-specific.
|
||||
Not all LUN types are supported.
|
||||
Currently CTL only supports Direct Access (type 0) and Processor (type 3)
|
||||
LUNs.
|
||||
Currently CTL supports Direct Access (type 0), Processor (type 3)
|
||||
and CD/DVD (type 5) LUNs.
|
||||
The backend requested may or may not support all of the LUN types that CTL
|
||||
supports.
|
||||
.El
|
||||
@ -876,6 +875,8 @@ Set to "off", disables read caching for the LUN, if supported by the backend.
|
||||
.It Va readonly
|
||||
Set to "on", blocks all media write operations to the LUN, reporting it
|
||||
as write protected.
|
||||
.It Va removable
|
||||
Set to "on", makes LUN removable.
|
||||
.It Va reordering
|
||||
Set to "unrestricted", allows target to process commands with SIMPLE task
|
||||
attribute in arbitrary order. Any data integrity exposures related to
|
||||
|
@ -28,7 +28,7 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd September 15, 2015
|
||||
.Dd September 27, 2015
|
||||
.Dt CTL.CONF 5
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -394,6 +394,10 @@ By default CTL allocates those IDs dynamically, but explicit specification
|
||||
may be needed for consistency in HA configurations.
|
||||
.It Ic device-id Ar string
|
||||
The SCSI Device Identification string presented to the initiator.
|
||||
.It Ic device-type Ar type
|
||||
Specify the SCSI device type to use when creating the LUN.
|
||||
Currently CTL supports Direct Access (type 0), Processor (type 3)
|
||||
and CD/DVD (type 5) LUNs.
|
||||
.It Ic option Ar name Ar value
|
||||
The CTL-specific options passed to the kernel.
|
||||
All CTL-specific options are documented in the
|
||||
|
@ -1455,6 +1455,13 @@ lun_set_blocksize(struct lun *lun, size_t value)
|
||||
lun->l_blocksize = value;
|
||||
}
|
||||
|
||||
void
|
||||
lun_set_device_type(struct lun *lun, uint8_t value)
|
||||
{
|
||||
|
||||
lun->l_device_type = value;
|
||||
}
|
||||
|
||||
void
|
||||
lun_set_device_id(struct lun *lun, const char *value)
|
||||
{
|
||||
|
@ -164,6 +164,7 @@ struct lun {
|
||||
TAILQ_HEAD(, lun_option) l_options;
|
||||
char *l_name;
|
||||
char *l_backend;
|
||||
uint8_t l_device_type;
|
||||
int l_blocksize;
|
||||
char *l_device_id;
|
||||
char *l_path;
|
||||
@ -375,6 +376,7 @@ struct lun *lun_new(struct conf *conf, const char *name);
|
||||
void lun_delete(struct lun *lun);
|
||||
struct lun *lun_find(const struct conf *conf, const char *name);
|
||||
void lun_set_backend(struct lun *lun, const char *value);
|
||||
void lun_set_device_type(struct lun *lun, uint8_t value);
|
||||
void lun_set_blocksize(struct lun *lun, size_t value);
|
||||
void lun_set_device_id(struct lun *lun, const char *value);
|
||||
void lun_set_path(struct lun *lun, const char *value);
|
||||
|
@ -108,6 +108,7 @@ struct cctl_lun_nv {
|
||||
struct cctl_lun {
|
||||
uint64_t lun_id;
|
||||
char *backend_type;
|
||||
uint8_t device_type;
|
||||
uint64_t size_blocks;
|
||||
uint32_t blocksize;
|
||||
char *serial_number;
|
||||
@ -221,6 +222,8 @@ cctl_end_element(void *user_data, const char *name)
|
||||
if (strcmp(name, "backend_type") == 0) {
|
||||
cur_lun->backend_type = str;
|
||||
str = NULL;
|
||||
} else if (strcmp(name, "lun_type") == 0) {
|
||||
cur_lun->device_type = strtoull(str, NULL, 0);
|
||||
} else if (strcmp(name, "size") == 0) {
|
||||
cur_lun->size_blocks = strtoull(str, NULL, 0);
|
||||
} else if (strcmp(name, "blocksize") == 0) {
|
||||
@ -610,6 +613,7 @@ conf_new_from_kernel(void)
|
||||
continue;
|
||||
}
|
||||
lun_set_backend(cl, lun->backend_type);
|
||||
lun_set_device_type(cl, lun->device_type);
|
||||
lun_set_blocksize(cl, lun->blocksize);
|
||||
lun_set_device_id(cl, lun->device_id);
|
||||
lun_set_serial(cl, lun->serial_number);
|
||||
@ -668,7 +672,7 @@ kernel_lun_add(struct lun *lun)
|
||||
}
|
||||
|
||||
req.reqdata.create.flags |= CTL_LUN_FLAG_DEV_TYPE;
|
||||
req.reqdata.create.device_type = T_DIRECT;
|
||||
req.reqdata.create.device_type = lun->l_device_type;
|
||||
|
||||
if (lun->l_serial != NULL) {
|
||||
strncpy(req.reqdata.create.serial_num, lun->l_serial,
|
||||
|
@ -57,8 +57,8 @@ extern void yyrestart(FILE *);
|
||||
%}
|
||||
|
||||
%token ALIAS AUTH_GROUP AUTH_TYPE BACKEND BLOCKSIZE CHAP CHAP_MUTUAL
|
||||
%token CLOSING_BRACKET CTL_LUN DEBUG DEVICE_ID DISCOVERY_AUTH_GROUP
|
||||
%token DISCOVERY_FILTER FOREIGN
|
||||
%token CLOSING_BRACKET CTL_LUN DEBUG DEVICE_ID DEVICE_TYPE
|
||||
%token DISCOVERY_AUTH_GROUP DISCOVERY_FILTER FOREIGN
|
||||
%token INITIATOR_NAME INITIATOR_PORTAL ISNS_SERVER ISNS_PERIOD ISNS_TIMEOUT
|
||||
%token LISTEN LISTEN_ISER LUN MAXPROC OFFLOAD OPENING_BRACKET OPTION
|
||||
%token PATH PIDFILE PORT PORTAL_GROUP REDIRECT SEMICOLON SERIAL SIZE STR
|
||||
@ -855,6 +855,8 @@ lun_entry:
|
||||
|
|
||||
lun_device_id
|
||||
|
|
||||
lun_device_type
|
||||
|
|
||||
lun_ctl_lun
|
||||
|
|
||||
lun_option
|
||||
@ -914,6 +916,31 @@ lun_device_id: DEVICE_ID STR
|
||||
}
|
||||
;
|
||||
|
||||
lun_device_type: DEVICE_TYPE STR
|
||||
{
|
||||
uint64_t tmp;
|
||||
|
||||
if (strcasecmp($2, "disk") == 0 ||
|
||||
strcasecmp($2, "direct") == 0)
|
||||
tmp = 0;
|
||||
else if (strcasecmp($2, "processor") == 0)
|
||||
tmp = 3;
|
||||
else if (strcasecmp($2, "cd") == 0 ||
|
||||
strcasecmp($2, "cdrom") == 0 ||
|
||||
strcasecmp($2, "dvd") == 0 ||
|
||||
strcasecmp($2, "dvdrom") == 0)
|
||||
tmp = 5;
|
||||
else if (expand_number($2, &tmp) != 0 ||
|
||||
tmp > 15) {
|
||||
yyerror("invalid numeric value");
|
||||
free($2);
|
||||
return (1);
|
||||
}
|
||||
|
||||
lun_set_device_type(lun, tmp);
|
||||
}
|
||||
;
|
||||
|
||||
lun_ctl_lun: CTL_LUN STR
|
||||
{
|
||||
uint64_t tmp;
|
||||
|
@ -57,6 +57,7 @@ chap-mutual { return CHAP_MUTUAL; }
|
||||
ctl-lun { return CTL_LUN; }
|
||||
debug { return DEBUG; }
|
||||
device-id { return DEVICE_ID; }
|
||||
device-type { return DEVICE_TYPE; }
|
||||
discovery-auth-group { return DISCOVERY_AUTH_GROUP; }
|
||||
discovery-filter { return DISCOVERY_FILTER; }
|
||||
foreign { return FOREIGN; }
|
||||
|
Loading…
Reference in New Issue
Block a user