Add support for BLOCK LIMITS VPD page
Signed-off-by: Ronnie Sahlberg <ronniesahlberg@gmail.com>
This commit is contained in:
@@ -293,6 +293,7 @@ enum scsi_inquiry_pagecode {
|
||||
SCSI_INQUIRY_PAGECODE_SUPPORTED_VPD_PAGES = 0x00,
|
||||
SCSI_INQUIRY_PAGECODE_UNIT_SERIAL_NUMBER = 0x80,
|
||||
SCSI_INQUIRY_PAGECODE_DEVICE_IDENTIFICATION = 0x83,
|
||||
SCSI_INQUIRY_PAGECODE_BLOCK_LIMITS = 0xB0,
|
||||
SCSI_INQUIRY_PAGECODE_BLOCK_DEVICE_CHARACTERISTICS = 0xB1,
|
||||
SCSI_INQUIRY_PAGECODE_LOGICAL_BLOCK_PROVISIONING = 0xB2
|
||||
};
|
||||
@@ -308,6 +309,25 @@ struct scsi_inquiry_supported_pages {
|
||||
unsigned char *pages;
|
||||
};
|
||||
|
||||
struct scsi_inquiry_block_limits {
|
||||
enum scsi_inquiry_peripheral_qualifier periperal_qualifier;
|
||||
enum scsi_inquiry_peripheral_device_type periperal_device_type;
|
||||
enum scsi_inquiry_pagecode pagecode;
|
||||
|
||||
int wsnz; /* write same no zero */
|
||||
uint8_t max_cmp; /* maximum_compare_and_write_length */
|
||||
uint16_t opt_gran; /* optimal_transfer_length_granularity */
|
||||
uint32_t max_xfer_len; /* maximum_transfer_length */
|
||||
uint32_t opt_xfer_len; /* optimal_transfer_length */
|
||||
uint32_t max_prefetch; /* maximum_prefetched_xdread_xdwrite_transfer_length */
|
||||
uint32_t max_unmap; /* maximum_unmap_lba_count */
|
||||
uint32_t max_unmap_bdc; /* maximum_unmap_block_descriptor_count */
|
||||
uint32_t opt_unmap_gran; /* optimal_unmap_granularity */
|
||||
int ugavalid;
|
||||
uint32_t unmap_gran_align; /* unmap_granularity_alignment */
|
||||
uint64_t max_ws_len; /* maximum_write_same_length */
|
||||
};
|
||||
|
||||
struct scsi_inquiry_block_device_characteristics {
|
||||
enum scsi_inquiry_peripheral_qualifier periperal_qualifier;
|
||||
enum scsi_inquiry_peripheral_device_type periperal_device_type;
|
||||
|
||||
@@ -371,13 +371,13 @@ scsi_inquiry_datain_getfullsize(struct scsi_task *task)
|
||||
|
||||
switch (task->params.inquiry.page_code) {
|
||||
case SCSI_INQUIRY_PAGECODE_SUPPORTED_VPD_PAGES:
|
||||
return task->datain.data[3] + 4;
|
||||
case SCSI_INQUIRY_PAGECODE_BLOCK_DEVICE_CHARACTERISTICS:
|
||||
case SCSI_INQUIRY_PAGECODE_UNIT_SERIAL_NUMBER:
|
||||
return task->datain.data[3] + 4;
|
||||
case SCSI_INQUIRY_PAGECODE_DEVICE_IDENTIFICATION:
|
||||
return ntohs(*(uint16_t *)&task->datain.data[2]) + 4;
|
||||
case SCSI_INQUIRY_PAGECODE_BLOCK_DEVICE_CHARACTERISTICS:
|
||||
return task->datain.data[3] + 4;
|
||||
case SCSI_INQUIRY_PAGECODE_BLOCK_LIMITS:
|
||||
case SCSI_INQUIRY_PAGECODE_LOGICAL_BLOCK_PROVISIONING:
|
||||
return ntohs(*(uint16_t *)&task->datain.data[2]) + 4;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
@@ -522,6 +522,34 @@ scsi_inquiry_datain_unmarshall(struct scsi_task *task)
|
||||
|
||||
dptr += dev->designator_length + 4;
|
||||
}
|
||||
return inq;
|
||||
} else if (task->params.inquiry.page_code
|
||||
== SCSI_INQUIRY_PAGECODE_BLOCK_LIMITS) {
|
||||
struct scsi_inquiry_block_limits *inq;
|
||||
|
||||
inq = scsi_malloc(task,
|
||||
sizeof(struct scsi_inquiry_block_limits));
|
||||
if (inq == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
inq->periperal_qualifier = (task->datain.data[0]>>5)&0x07;
|
||||
inq->periperal_device_type = task->datain.data[0]&0x1f;
|
||||
inq->pagecode = task->datain.data[1];
|
||||
|
||||
inq->wsnz = task->datain.data[4] & 0x01;
|
||||
inq->max_cmp = task->datain.data[5];
|
||||
inq->opt_gran = ntohs(*(uint16_t *)&task->datain.data[6]);
|
||||
inq->max_xfer_len = ntohl(*(uint32_t *)&task->datain.data[8]);
|
||||
inq->opt_xfer_len = ntohl(*(uint32_t *)&task->datain.data[12]);
|
||||
inq->max_prefetch = ntohl(*(uint32_t *)&task->datain.data[16]);
|
||||
inq->max_unmap = ntohl(*(uint32_t *)&task->datain.data[20]);
|
||||
inq->max_unmap_bdc = ntohl(*(uint32_t *)&task->datain.data[24]);
|
||||
inq->opt_unmap_gran = ntohl(*(uint32_t *)&task->datain.data[28]);
|
||||
inq->ugavalid = !!(task->datain.data[32]&0x80);
|
||||
inq->unmap_gran_align = ntohl(*(uint32_t *)&task->datain.data[32]) & 0x7fffffff;
|
||||
inq->max_ws_len = ntohl(*(uint32_t *)&task->datain.data[36]);
|
||||
inq->max_ws_len = (inq->max_ws_len << 32) | ntohl(*(uint32_t *)&task->datain.data[40]);
|
||||
|
||||
return inq;
|
||||
} else if (task->params.inquiry.page_code
|
||||
== SCSI_INQUIRY_PAGECODE_BLOCK_DEVICE_CHARACTERISTICS) {
|
||||
@@ -536,8 +564,7 @@ scsi_inquiry_datain_unmarshall(struct scsi_task *task)
|
||||
inq->periperal_device_type = task->datain.data[0]&0x1f;
|
||||
inq->pagecode = task->datain.data[1];
|
||||
|
||||
inq->medium_rotation_rate = ntohs(*(uint16_t *)
|
||||
&task->datain.data[4]);
|
||||
inq->medium_rotation_rate = ntohs(*(uint16_t *)&task->datain.data[4]);
|
||||
return inq;
|
||||
} else if (task->params.inquiry.page_code
|
||||
== SCSI_INQUIRY_PAGECODE_LOGICAL_BLOCK_PROVISIONING) {
|
||||
|
||||
@@ -27,6 +27,22 @@
|
||||
const char *initiator = "iqn.2010-11.ronnie:iscsi-inq";
|
||||
|
||||
|
||||
void inquiry_block_limits(struct scsi_inquiry_block_limits *inq)
|
||||
{
|
||||
printf("wsnz:%d\n", inq->wsnz);
|
||||
printf("maximum compare and write length:%d\n", inq->max_cmp);
|
||||
printf("optimal transfer length granularity:%d\n", inq->opt_gran);
|
||||
printf("maximum transfer length:%d\n", inq->max_xfer_len);
|
||||
printf("optimal transfer length:%d\n",inq->opt_xfer_len);
|
||||
printf("maximum prefetch xdread xdwrite transfer length:%d\n", inq->max_prefetch);
|
||||
printf("maximum unmap lba count:%d\n", inq->max_unmap);
|
||||
printf("maximum unmap block descriptor count:%d\n", inq->max_unmap_bdc);
|
||||
printf("optimal unmap granularity:%d\n", inq->opt_unmap_gran);
|
||||
printf("ugavalid:%d\n", inq->ugavalid);
|
||||
printf("unmap granularity alignment:%d\n", inq->unmap_gran_align);
|
||||
printf("maximum write same length:%d\n", (int)inq->max_ws_len);
|
||||
}
|
||||
|
||||
void inquiry_logical_block_provisioning(struct scsi_inquiry_logical_block_provisioning *inq)
|
||||
{
|
||||
printf("Threshold Exponent:%d\n", inq->threshold_exponent);
|
||||
@@ -151,6 +167,9 @@ void do_inquiry(struct iscsi_context *iscsi, int lun, int evpd, int pc)
|
||||
case SCSI_INQUIRY_PAGECODE_DEVICE_IDENTIFICATION:
|
||||
inquiry_device_identification(inq);
|
||||
break;
|
||||
case SCSI_INQUIRY_PAGECODE_BLOCK_LIMITS:
|
||||
inquiry_block_limits(inq);
|
||||
break;
|
||||
case SCSI_INQUIRY_PAGECODE_BLOCK_DEVICE_CHARACTERISTICS:
|
||||
inquiry_block_device_characteristics(inq);
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user