[Stgt-devel] [PATCH 4/4] OSD command parser
Ming Zhang
blackmagic02881
Mon Jan 22 20:35:10 CET 2007
On Mon, 2007-01-22 at 14:22 -0500, Ming Zhang wrote:
> 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?
ok i found it called in inquiry() which check target type again.
not a good idea. suggest to keep in a way like IET code, for each target
type, call its foo_cmd_perform(), and make some common spc function as
helper functions.
>
> > +{
> > + 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