svn commit: r279654 - head/usr.sbin/bhyve

Alexander Motin mav at FreeBSD.org
Thu Mar 5 12:21:14 UTC 2015


Author: mav
Date: Thu Mar  5 12:21:12 2015
New Revision: 279654
URL: https://svnweb.freebsd.org/changeset/base/279654

Log:
  Report logical/physical sector sizes for virtual SATA disk.
  
  MFC after:	2 weeks

Modified:
  head/usr.sbin/bhyve/block_if.c
  head/usr.sbin/bhyve/block_if.h
  head/usr.sbin/bhyve/pci_ahci.c

Modified: head/usr.sbin/bhyve/block_if.c
==============================================================================
--- head/usr.sbin/bhyve/block_if.c	Thu Mar  5 11:43:12 2015	(r279653)
+++ head/usr.sbin/bhyve/block_if.c	Thu Mar  5 12:21:12 2015	(r279654)
@@ -83,6 +83,8 @@ struct blockif_ctxt {
 	int			bc_rdonly;
 	off_t			bc_size;
 	int			bc_sectsz;
+	int			bc_psectsz;
+	int			bc_psectoff;
 	pthread_t		bc_btid;
         pthread_mutex_t		bc_mtx;
         pthread_cond_t		bc_cond;
@@ -268,7 +270,7 @@ blockif_open(const char *optstr, const c
 	char *nopt, *xopts;
 	struct blockif_ctxt *bc;
 	struct stat sbuf;
-	off_t size;
+	off_t size, psectsz, psectoff;
 	int extra, fd, i, sectsz;
 	int nocache, sync, ro;
 
@@ -323,6 +325,7 @@ blockif_open(const char *optstr, const c
 	 */
         size = sbuf.st_size;
 	sectsz = DEV_BSIZE;
+	psectsz = psectoff = 0;
 	if (S_ISCHR(sbuf.st_mode)) {
 		if (ioctl(fd, DIOCGMEDIASIZE, &size) < 0 ||
 		    ioctl(fd, DIOCGSECTORSIZE, &sectsz)) {
@@ -332,7 +335,10 @@ blockif_open(const char *optstr, const c
 		}
 		assert(size != 0);
 		assert(sectsz != 0);
-	}
+		if (ioctl(fd, DIOCGSTRIPESIZE, &psectsz) == 0 && psectsz > 0)
+			ioctl(fd, DIOCGSTRIPEOFFSET, &psectoff);
+	} else
+		psectsz = sbuf.st_blksize;
 
 	bc = calloc(1, sizeof(struct blockif_ctxt));
 	if (bc == NULL) {
@@ -345,6 +351,8 @@ blockif_open(const char *optstr, const c
 	bc->bc_rdonly = ro;
 	bc->bc_size = size;
 	bc->bc_sectsz = sectsz;
+	bc->bc_psectsz = psectsz;
+	bc->bc_psectoff = psectoff;
 	pthread_mutex_init(&bc->bc_mtx, NULL);
 	pthread_cond_init(&bc->bc_cond, NULL);
 	TAILQ_INIT(&bc->bc_freeq);
@@ -595,6 +603,15 @@ blockif_sectsz(struct blockif_ctxt *bc)
 	return (bc->bc_sectsz);
 }
 
+void
+blockif_psectsz(struct blockif_ctxt *bc, int *size, int *off)
+{
+
+	assert(bc->bc_magic == BLOCKIF_SIG);
+	*size = bc->bc_psectsz;
+	*off = bc->bc_psectoff;
+}
+
 int
 blockif_queuesz(struct blockif_ctxt *bc)
 {

Modified: head/usr.sbin/bhyve/block_if.h
==============================================================================
--- head/usr.sbin/bhyve/block_if.h	Thu Mar  5 11:43:12 2015	(r279653)
+++ head/usr.sbin/bhyve/block_if.h	Thu Mar  5 12:21:12 2015	(r279654)
@@ -55,6 +55,7 @@ off_t	blockif_size(struct blockif_ctxt *
 void	blockif_chs(struct blockif_ctxt *bc, uint16_t *c, uint8_t *h,
     uint8_t *s);
 int	blockif_sectsz(struct blockif_ctxt *bc);
+void	blockif_psectsz(struct blockif_ctxt *bc, int *size, int *off);
 int	blockif_queuesz(struct blockif_ctxt *bc);
 int	blockif_is_ro(struct blockif_ctxt *bc);
 int	blockif_read(struct blockif_ctxt *bc, struct blockif_req *breq);

Modified: head/usr.sbin/bhyve/pci_ahci.c
==============================================================================
--- head/usr.sbin/bhyve/pci_ahci.c	Thu Mar  5 11:43:12 2015	(r279653)
+++ head/usr.sbin/bhyve/pci_ahci.c	Thu Mar  5 12:21:12 2015	(r279654)
@@ -684,11 +684,14 @@ handle_identify(struct ahci_port *p, int
 	} else {
 		uint16_t buf[256];
 		uint64_t sectors;
+		int sectsz, psectsz, psectoff;
 		uint16_t cyl;
 		uint8_t sech, heads;
 
-		sectors = blockif_size(p->bctx) / blockif_sectsz(p->bctx);
+		sectsz = blockif_sectsz(p->bctx);
+		sectors = blockif_size(p->bctx) / sectsz;
 		blockif_chs(p->bctx, &cyl, &heads, &sech);
+		blockif_psectsz(p->bctx, &psectsz, &psectoff);
 		memset(buf, 0, sizeof(buf));
 		buf[0] = 0x0040;
 		buf[1] = cyl;
@@ -733,6 +736,18 @@ handle_identify(struct ahci_port *p, int
 		buf[101] = (sectors >> 16);
 		buf[102] = (sectors >> 32);
 		buf[103] = (sectors >> 48);
+		buf[106] = 0x4000;
+		buf[209] = 0x4000;
+		if (psectsz > sectsz) {
+			buf[106] |= 0x2000;
+			buf[106] |= ffsl(psectsz / sectsz) - 1;
+			buf[209] |= (psectoff / sectsz);
+		}
+		if (sectsz > 512) {
+			buf[106] |= 0x1000;
+			buf[117] = sectsz / 2;
+			buf[118] = ((sectsz / 2) >> 16);
+		}
 		ahci_write_fis_piosetup(p);
 		write_prdt(p, slot, cfis, (void *)buf, sizeof(buf));
 		p->tfd = ATA_S_DSC | ATA_S_READY;


More information about the svn-src-all mailing list