[Stgt-devel] [PATCH 4/4] OSD command parser
Ming Zhang
blackmagic02881
Mon Jan 22 20:21:59 CET 2007
On Mon, 2007-01-22 at 14:08 -0500, Pete Wyckoff wrote:
<snip>
> +
> +/*
> + * OSD-specific inquiry.
> + */
> +int osd_inquiry(struct tgt_device *dev, int host_no, uint8_t *lun_buf,
> + uint8_t *scb, uint8_t *data, int *len)
where this osd_inquiry get called?
> +{
> + int result = SAM_STAT_CHECK_CONDITION;
> +
> + /* EVPD means need a page code */
> + if ((scb[1] & 0x3) == 0 && scb[2] != 0)
> + return result;
> +
> + dprintf("%x %x\n", scb[1], scb[2]);
> +
> + data[0] = TYPE_OSD;
> + if (!dev)
> + data[0] = TYPE_NO_LUN;
> +
> + if ((scb[1] & 0x1) == 0) {
> + /* evpd == 0, standard inquiry */
> + dprintf("standard inquiry\n");
> + data[2] = 5; /* modern version */
> + data[3] = 0x02; /* modern response format */
> + data[7] = 0x02; /* support command queueing */
> + memset(data + 8, 0x20, 28);
> + memcpy(data + 8,
> + VENDOR_ID, min_t(size_t, strlen(VENDOR_ID), 8));
> + memcpy(data + 16,
> + PRODUCT_ID, min_t(size_t, strlen(PRODUCT_ID), 16));
> + memcpy(data + 32,
> + PRODUCT_REV, min_t(size_t, strlen(PRODUCT_REV), 4));
> + *len = 36;
> + if (dev) {
> + data[58] = 0x03;
> + data[59] = 0x40; /* osd */
> + data[60] = 0x09;
> + data[61] = 0x60; /* iscsi */
> + data[62] = 0x03;
> + data[63] = 0x00; /* spc3 */
> + *len = 64;
> + }
> + data[4] = *len - 5; /* additional length */
> + result = SAM_STAT_GOOD;
> + } else {
> + /* request particular page code */
> + dprintf("page %x\n", scb[2]);
> + if (!dev)
> + return result;
> + data[1] = scb[2];
> + if (scb[2] == 0x0) {
> + /* supported VPD pages */
> + data[3] = 3;
> + data[4] = 0x0;
> + data[5] = 0x80;
> + data[6] = 0x83;
> + *len = 7;
> + result = SAM_STAT_GOOD;
> + } else if (scb[2] == 0x80) {
> + /* unit serial number " " */
> + data[3] = 4;
> + memset(data + 4, 0x20, 4);
> + *len = 8;
> + result = SAM_STAT_GOOD;
> + } else if (scb[2] == 0x83) {
> + /* device identification */
> + data[3] = SCSI_ID_LEN + 4;
> + data[4] = 0x1;
> + data[5] = 0x1;
> + data[7] = SCSI_ID_LEN;
> + if (dev)
> + memcpy(data + 8, dev->scsi_id, SCSI_ID_LEN);
> + *len = SCSI_ID_LEN + 8;
> + result = SAM_STAT_GOOD;
> + }
> + }
> +
> + if (result != SAM_STAT_GOOD)
> + goto err;
> +
> + *len = min_t(int, *len, scb[4]);
> +
> + return SAM_STAT_GOOD;
> +
> +err:
> + *len = sense_data_build(data, 0x70, ILLEGAL_REQUEST,
> + 0x24, 0);
> + return SAM_STAT_CHECK_CONDITION;
> +}
> +
> +int osd_cmd_perform(uint8_t *cdb, int *len, uint32_t datalen,
> + unsigned long *uaddr, uint8_t *rw, uint8_t *try_map,
> + uint64_t *offset, struct tgt_device *dev, int *async,
> + void *key, bkio_submit_t *submit)
> +{
> + int ret = SAM_STAT_GOOD;
> + uint8_t *data = NULL;
> + uint16_t action;
> +
> + switch (cdb[0]) {
> + /* there are other optional non-varlen commands */
> + case VARLEN_CDB:
> + dprintf("cdb[0] %x datalen %u\n", cdb[0], datalen);
> + if (cdb[7] != 200-8)
> + eprintf("request size %d wrong, should be 200\n",
> + cdb[7]+8);
> +
> + action = (cdb[8] << 8) | cdb[9];
> +
> + switch (action) {
> + case OSD_APPEND:
> + case OSD_CREATE:
> + case OSD_CREATE_AND_WRITE:
> + case OSD_CREATE_COLLECTION:
> + case OSD_CREATE_PARTITION:
> + case OSD_FLUSH:
> + case OSD_FLUSH_COLLECTION:
> + case OSD_FLUSH_OSD:
> + case OSD_FLUSH_PARTITION:
> + case OSD_FORMAT_OSD:
> + case OSD_GET_ATTRIBUTES:
> + case OSD_GET_MEMBER_ATTRIBUTES:
> + case OSD_LIST:
> + case OSD_LIST_COLLECTION:
> + case OSD_PERFORM_SCSI_COMMAND:
> + case OSD_PERFORM_TASK_MGMT_FUNC:
> + case OSD_QUERY:
> + case OSD_READ:
> + case OSD_REMOVE:
> + case OSD_REMOVE_COLLECTION:
> + case OSD_REMOVE_MEMBER_OBJECTS:
> + case OSD_REMOVE_PARTITION:
> + case OSD_SET_ATTRIBUTES:
> + case OSD_SET_KEY:
> + case OSD_SET_MASTER_KEY:
> + case OSD_SET_MEMBER_ATTRIBUTES:
> + case OSD_WRITE:
> + ret = submit(dev, cdb, *rw, datalen, uaddr, *offset,
> + async, key);
> + if (ret == SAM_STAT_GOOD) {
> + *len = datalen;
> + } else {
> + data = get_zeroed_page();
> + *len = sense_data_build(data, 0x70,
> + ILLEGAL_REQUEST, 0x25,
> + 0);
> + }
> + break;
> + default:
> + eprintf("unknown service action 0x%04x\n", action);
> + }
> + break;
> + default:
> + eprintf("unknown command %x %u\n", cdb[0], datalen);
> + *len = 0;
> + break;
> + }
> +
> + if (data)
> + *uaddr = (unsigned long) data;
> +
> + return ret;
> +}
> +
> diff --git a/usr/scsi.c b/usr/scsi.c
> index 277924c..d102f5e 100644
> --- a/usr/scsi.c
> +++ b/usr/scsi.c
> @@ -357,6 +357,10 @@ int scsi_cmd_perform(uint64_t nid, int lid, int host_no, uint8_t *scb,
> result = block_cmd_perform(scb, len, datalen, uaddr, rw,
> try_map, offset, dev, async, key,
> submit);
> + else if (target_type == SCSI_TARGET_OSD)
> + result = osd_cmd_perform(scb, len, datalen, uaddr, rw,
> + try_map, offset, dev, async, key,
> + submit);
> else
> eprintf("unknown target type %d\n", target_type);
>
> diff --git a/usr/scsi.h b/usr/scsi.h
> index 154508d..20aa2a8 100644
> --- a/usr/scsi.h
> +++ b/usr/scsi.h
> @@ -69,6 +69,7 @@
> #define MODE_SENSE_10 0x5a
> #define PERSISTENT_RESERVE_IN 0x5e
> #define PERSISTENT_RESERVE_OUT 0x5f
> +#define VARLEN_CDB 0x7f
> #define REPORT_LUNS 0xa0
> #define MOVE_MEDIUM 0xa5
> #define EXCHANGE_MEDIUM 0xa6
> @@ -87,6 +88,35 @@
> #define SERVICE_ACTION_IN 0x9e
> #define SAI_READ_CAPACITY_16 0x10
>
> +/* varlen cdb service actions for OSD-2 (before SNIA changes 17 jan 07) */
> +#define OSD_APPEND 0x8807
> +#define OSD_CREATE 0x8802
> +#define OSD_CREATE_AND_WRITE 0x8812
> +#define OSD_CREATE_COLLECTION 0x8815
> +#define OSD_CREATE_PARTITION 0x880b
> +#define OSD_FLUSH 0x8808
> +#define OSD_FLUSH_COLLECTION 0x881a
> +#define OSD_FLUSH_OSD 0x881c
> +#define OSD_FLUSH_PARTITION 0x881b
> +#define OSD_FORMAT_OSD 0x8801
> +#define OSD_GET_ATTRIBUTES 0x880e
> +#define OSD_GET_MEMBER_ATTRIBUTES 0x8822
> +#define OSD_LIST 0x8803
> +#define OSD_LIST_COLLECTION 0x8817
> +#define OSD_PERFORM_SCSI_COMMAND 0x8f7e
> +#define OSD_PERFORM_TASK_MGMT_FUNC 0x8f7f
> +#define OSD_QUERY 0x8820
> +#define OSD_READ 0x8805
> +#define OSD_REMOVE 0x880a
> +#define OSD_REMOVE_COLLECTION 0x8816
> +#define OSD_REMOVE_MEMBER_OBJECTS 0x8821
> +#define OSD_REMOVE_PARTITION 0x880c
> +#define OSD_SET_ATTRIBUTES 0x880f
> +#define OSD_SET_KEY 0x8818
> +#define OSD_SET_MASTER_KEY 0x8819
> +#define OSD_SET_MEMBER_ATTRIBUTES 0x8823
> +#define OSD_WRITE 0x8806
> +
> #define SAM_STAT_GOOD 0x00
> #define SAM_STAT_CHECK_CONDITION 0x02
> #define SAM_STAT_CONDITION_MET 0x04
> @@ -127,6 +157,7 @@
> #define TYPE_RAID 0x0c
> #define TYPE_ENCLOSURE 0x0d
> #define TYPE_RBC 0x0e
> +#define TYPE_OSD 0x11
> #define TYPE_NO_LUN 0x7f
>
> #define MSG_SIMPLE_TAG 0x20
> diff --git a/usr/tgtd.h b/usr/tgtd.h
> index 262dc9c..3b75da3 100644
> --- a/usr/tgtd.h
> +++ b/usr/tgtd.h
> @@ -125,6 +125,12 @@ int block_cmd_perform(uint8_t *scb, int *len, uint32_t datalen,
> unsigned long *uaddr, uint8_t *rw, uint8_t *try_map,
> uint64_t *offset, struct tgt_device *dev, int *async,
> void *key, bkio_submit_t *submit);
> +int osd_inquiry(struct tgt_device *dev, int host_no, uint8_t *lun_buf,
> + uint8_t *scb, uint8_t *data, int *len);
> +int osd_cmd_perform(uint8_t *scb, int *len, uint32_t datalen,
> + unsigned long *uaddr, uint8_t *rw, uint8_t *try_map,
> + uint64_t *offset, struct tgt_device *dev, int *async,
> + void *key, bkio_submit_t *submit);
>
> extern int sense_data_build(uint8_t *data, uint8_t res_code, uint8_t key,
> uint8_t ascode, uint8_t ascodeq);
--
http://blackmagic02881.wordpress.com/
More information about the stgt
mailing list