[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