Add support for Long LBA mode parameter block descriptor.
It is formally required for SBC Base 2016 feature set. MFC after: 2 weeks
This commit is contained in:
parent
ba9b2ede8a
commit
ed3bf01599
@ -6365,13 +6365,12 @@ int
|
||||
ctl_mode_sense(struct ctl_scsiio *ctsio)
|
||||
{
|
||||
struct ctl_lun *lun = CTL_LUN(ctsio);
|
||||
int pc, page_code, dbd, subpage;
|
||||
int alloc_len, page_len, header_len, total_len;
|
||||
struct scsi_mode_block_descr *block_desc;
|
||||
int pc, page_code, llba, subpage;
|
||||
int alloc_len, page_len, header_len, bd_len, total_len;
|
||||
void *block_desc;
|
||||
struct ctl_page_index *page_index;
|
||||
|
||||
dbd = 0;
|
||||
block_desc = NULL;
|
||||
llba = 0;
|
||||
|
||||
CTL_DEBUG_PRINT(("ctl_mode_sense\n"));
|
||||
|
||||
@ -6383,9 +6382,10 @@ ctl_mode_sense(struct ctl_scsiio *ctsio)
|
||||
|
||||
header_len = sizeof(struct scsi_mode_hdr_6);
|
||||
if (cdb->byte2 & SMS_DBD)
|
||||
dbd = 1;
|
||||
bd_len = 0;
|
||||
else
|
||||
header_len += sizeof(struct scsi_mode_block_descr);
|
||||
bd_len = sizeof(struct scsi_mode_block_descr);
|
||||
header_len += bd_len;
|
||||
|
||||
pc = (cdb->page & SMS_PAGE_CTRL_MASK) >> 6;
|
||||
page_code = cdb->page & SMS_PAGE_CODE;
|
||||
@ -6399,11 +6399,18 @@ ctl_mode_sense(struct ctl_scsiio *ctsio)
|
||||
cdb = (struct scsi_mode_sense_10 *)ctsio->cdb;
|
||||
|
||||
header_len = sizeof(struct scsi_mode_hdr_10);
|
||||
if (cdb->byte2 & SMS_DBD) {
|
||||
bd_len = 0;
|
||||
} else if (lun->be_lun->lun_type == T_DIRECT) {
|
||||
if (cdb->byte2 & SMS10_LLBAA) {
|
||||
llba = 1;
|
||||
bd_len = sizeof(struct scsi_mode_block_descr_dlong);
|
||||
} else
|
||||
bd_len = sizeof(struct scsi_mode_block_descr_dshort);
|
||||
} else
|
||||
bd_len = sizeof(struct scsi_mode_block_descr);
|
||||
header_len += bd_len;
|
||||
|
||||
if (cdb->byte2 & SMS_DBD)
|
||||
dbd = 1;
|
||||
else
|
||||
header_len += sizeof(struct scsi_mode_block_descr);
|
||||
pc = (cdb->page & SMS_PAGE_CTRL_MASK) >> 6;
|
||||
page_code = cdb->page & SMS_PAGE_CODE;
|
||||
subpage = cdb->subpage;
|
||||
@ -6536,12 +6543,8 @@ ctl_mode_sense(struct ctl_scsiio *ctsio)
|
||||
(lun->MODE_CTRL.eca_and_aen & SCP_SWP) != 0)
|
||||
header->dev_specific |= 0x80; /* WP */
|
||||
}
|
||||
if (dbd)
|
||||
header->block_descr_len = 0;
|
||||
else
|
||||
header->block_descr_len =
|
||||
sizeof(struct scsi_mode_block_descr);
|
||||
block_desc = (struct scsi_mode_block_descr *)&header[1];
|
||||
header->block_descr_len = bd_len;
|
||||
block_desc = &header[1];
|
||||
break;
|
||||
}
|
||||
case MODE_SENSE_10: {
|
||||
@ -6558,12 +6561,10 @@ ctl_mode_sense(struct ctl_scsiio *ctsio)
|
||||
(lun->MODE_CTRL.eca_and_aen & SCP_SWP) != 0)
|
||||
header->dev_specific |= 0x80; /* WP */
|
||||
}
|
||||
if (dbd)
|
||||
scsi_ulto2b(0, header->block_descr_len);
|
||||
else
|
||||
scsi_ulto2b(sizeof(struct scsi_mode_block_descr),
|
||||
header->block_descr_len);
|
||||
block_desc = (struct scsi_mode_block_descr *)&header[1];
|
||||
if (llba)
|
||||
header->flags |= SMH_LONGLBA;
|
||||
scsi_ulto2b(bd_len, header->block_descr_len);
|
||||
block_desc = &header[1];
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@ -6574,12 +6575,27 @@ ctl_mode_sense(struct ctl_scsiio *ctsio)
|
||||
* If we've got a disk, use its blocksize in the block
|
||||
* descriptor. Otherwise, just set it to 0.
|
||||
*/
|
||||
if (dbd == 0) {
|
||||
if (lun->be_lun->lun_type == T_DIRECT)
|
||||
scsi_ulto3b(lun->be_lun->blocksize,
|
||||
block_desc->block_len);
|
||||
else
|
||||
scsi_ulto3b(0, block_desc->block_len);
|
||||
if (bd_len > 0) {
|
||||
if (lun->be_lun->lun_type == T_DIRECT) {
|
||||
if (llba) {
|
||||
struct scsi_mode_block_descr_dlong *bd = block_desc;
|
||||
if (lun->be_lun->maxlba != 0)
|
||||
scsi_u64to8b(lun->be_lun->maxlba + 1,
|
||||
bd->num_blocks);
|
||||
scsi_ulto4b(lun->be_lun->blocksize,
|
||||
bd->block_len);
|
||||
} else {
|
||||
struct scsi_mode_block_descr_dshort *bd = block_desc;
|
||||
if (lun->be_lun->maxlba != 0)
|
||||
scsi_ulto4b(MIN(lun->be_lun->maxlba+1,
|
||||
UINT32_MAX), bd->num_blocks);
|
||||
scsi_ulto3b(lun->be_lun->blocksize,
|
||||
bd->block_len);
|
||||
}
|
||||
} else {
|
||||
struct scsi_mode_block_descr *bd = block_desc;
|
||||
scsi_ulto3b(0, bd->block_len);
|
||||
}
|
||||
}
|
||||
|
||||
switch (page_code) {
|
||||
|
@ -264,7 +264,9 @@ struct scsi_mode_hdr_10
|
||||
u_int8_t datalen[2];
|
||||
u_int8_t medium_type;
|
||||
u_int8_t dev_specific;
|
||||
u_int8_t reserved[2];
|
||||
u_int8_t flags;
|
||||
#define SMH_LONGLBA 0x01
|
||||
u_int8_t reserved;
|
||||
u_int8_t block_descr_len[2];
|
||||
};
|
||||
|
||||
@ -276,6 +278,20 @@ struct scsi_mode_block_descr
|
||||
u_int8_t block_len[3];
|
||||
};
|
||||
|
||||
struct scsi_mode_block_descr_dshort
|
||||
{
|
||||
u_int8_t num_blocks[4];
|
||||
u_int8_t reserved;
|
||||
u_int8_t block_len[3];
|
||||
};
|
||||
|
||||
struct scsi_mode_block_descr_dlong
|
||||
{
|
||||
u_int8_t num_blocks[8];
|
||||
u_int8_t reserved[4];
|
||||
u_int8_t block_len[4];
|
||||
};
|
||||
|
||||
struct scsi_per_res_in
|
||||
{
|
||||
u_int8_t opcode;
|
||||
|
Loading…
x
Reference in New Issue
Block a user