Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 6 Apr 2014 10:13:15 +0000 (UTC)
From:      Alexander Motin <mav@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r264191 - head/sys/cam/ctl
Message-ID:  <201404061013.s36ADFE8020632@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mav
Date: Sun Apr  6 10:13:14 2014
New Revision: 264191
URL: http://svnweb.freebsd.org/changeset/base/264191

Log:
  Report stripe size and offset of the backing device in READ CAPACITY (16)
  as physical sector size and offset.
  
  MFC after:	2 weeks

Modified:
  head/sys/cam/ctl/ctl.c
  head/sys/cam/ctl/ctl_backend.h
  head/sys/cam/ctl/ctl_backend_block.c

Modified: head/sys/cam/ctl/ctl.c
==============================================================================
--- head/sys/cam/ctl/ctl.c	Sun Apr  6 09:14:11 2014	(r264190)
+++ head/sys/cam/ctl/ctl.c	Sun Apr  6 10:13:14 2014	(r264191)
@@ -6907,6 +6907,8 @@ ctl_read_capacity_16(struct ctl_scsiio *
 	scsi_u64to8b(lun->be_lun->maxlba, data->addr);
 	/* XXX KDM this may not be 512 bytes... */
 	scsi_ulto4b(lun->be_lun->blocksize, data->length);
+	data->prot_lbppbe = lun->be_lun->pblockexp & SRC16_LBPPBE;
+	scsi_ulto2b(lun->be_lun->pblockoff & SRC16_LALBA_A, data->lalba_lbp);
 
 	ctsio->scsi_status = SCSI_STATUS_OK;
 

Modified: head/sys/cam/ctl/ctl_backend.h
==============================================================================
--- head/sys/cam/ctl/ctl_backend.h	Sun Apr  6 09:14:11 2014	(r264190)
+++ head/sys/cam/ctl/ctl_backend.h	Sun Apr  6 10:13:14 2014	(r264191)
@@ -137,6 +137,10 @@ typedef void (*be_lun_config_t)(void *be
  * this should be 512.  In theory CTL should be able to handle other block
  * sizes.  Host application software may not deal with it very well, though.
  *
+ * pblockexp is the log2() of number of LBAs on the LUN per physical sector.
+ *
+ * pblockoff is the lowest LBA on the LUN aligned ot physical sector.
+ *
  * req_lun_id is the requested LUN ID.  CTL only pays attention to this
  * field if the CTL_LUN_FLAG_ID_REQ flag is set.  If the requested LUN ID is
  * not available, the LUN addition will fail.  If a particular LUN ID isn't
@@ -185,6 +189,8 @@ struct ctl_be_lun {
 	void			*be_lun;	/* passed to CTL */
 	uint64_t		maxlba;		/* passed to CTL */
 	uint32_t		blocksize;	/* passed to CTL */
+	uint16_t		pblockexp;	/* passed to CTL */
+	uint16_t		pblockoff;	/* passed to CTL */
 	uint32_t		req_lun_id;	/* passed to CTL */
 	uint32_t		lun_id;		/* returned from CTL */
 	uint8_t			serial_num[CTL_SN_LEN];	 /* passed to CTL */

Modified: head/sys/cam/ctl/ctl_backend_block.c
==============================================================================
--- head/sys/cam/ctl/ctl_backend_block.c	Sun Apr  6 09:14:11 2014	(r264190)
+++ head/sys/cam/ctl/ctl_backend_block.c	Sun Apr  6 10:13:14 2014	(r264191)
@@ -156,6 +156,8 @@ struct ctl_be_block_lun {
 	uint64_t size_bytes;
 	uint32_t blocksize;
 	int blocksize_shift;
+	uint16_t pblockexp;
+	uint16_t pblockoff;
 	struct ctl_be_block_softc *softc;
 	struct devstat *disk_stats;
 	ctl_be_block_lun_flags flags;
@@ -1262,6 +1264,7 @@ ctl_be_block_open_dev(struct ctl_be_bloc
 	struct cdev		     *dev;
 	struct cdevsw		     *devsw;
 	int			      error;
+	off_t			      ps, pss, po, pos;
 
 	params = &req->reqdata.create;
 
@@ -1359,6 +1362,24 @@ ctl_be_block_open_dev(struct ctl_be_bloc
 		be_lun->size_bytes = params->lun_size_bytes;
 	}
 
+	error = devsw->d_ioctl(dev, DIOCGSTRIPESIZE,
+			       (caddr_t)&ps, FREAD, curthread);
+	if (error)
+		ps = po = 0;
+	else {
+		error = devsw->d_ioctl(dev, DIOCGSTRIPEOFFSET,
+				       (caddr_t)&po, FREAD, curthread);
+		if (error)
+			po = 0;
+	}
+	pss = ps / be_lun->blocksize;
+	pos = po / be_lun->blocksize;
+	if ((pss > 0) && (pss * be_lun->blocksize == ps) && (pss >= pos) &&
+	    ((pss & (pss - 1)) == 0) && (pos * be_lun->blocksize == po)) {
+		be_lun->pblockexp = fls(pss) - 1;
+		be_lun->pblockoff = (pss - pos) % pss;
+	}
+
 	return (0);
 }
 
@@ -1583,6 +1604,8 @@ ctl_be_block_create(struct ctl_be_block_
 		 * For processor devices, we don't have any size.
 		 */
 		be_lun->blocksize = 0;
+		be_lun->pblockexp = 0;
+		be_lun->pblockoff = 0;
 		be_lun->size_blocks = 0;
 		be_lun->size_bytes = 0;
 		be_lun->ctl_be_lun.maxlba = 0;
@@ -1643,6 +1666,8 @@ ctl_be_block_create(struct ctl_be_block_
 	be_lun->ctl_be_lun.flags = CTL_LUN_FLAG_PRIMARY;
 	be_lun->ctl_be_lun.be_lun = be_lun;
 	be_lun->ctl_be_lun.blocksize = be_lun->blocksize;
+	be_lun->ctl_be_lun.pblockexp = be_lun->pblockexp;
+	be_lun->ctl_be_lun.pblockoff = be_lun->pblockoff;
 	/* Tell the user the blocksize we ended up using */
 	params->blocksize_bytes = be_lun->blocksize;
 	if (params->flags & CTL_LUN_FLAG_ID_REQ) {



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201404061013.s36ADFE8020632>