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, §sz)) {
@@ -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