summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormav <mav@FreeBSD.org>2015-03-05 12:21:12 +0000
committermav <mav@FreeBSD.org>2015-03-05 12:21:12 +0000
commit02e846756ee99b849987a9bb6f57566fc70360c7 (patch)
tree53048cec54b0070e12ef19718de747eee4534847
parent214386b6e7dba79b7f68348c27e501facbe61377 (diff)
downloadFreeBSD-src-02e846756ee99b849987a9bb6f57566fc70360c7.zip
FreeBSD-src-02e846756ee99b849987a9bb6f57566fc70360c7.tar.gz
Report logical/physical sector sizes for virtual SATA disk.
MFC after: 2 weeks
-rw-r--r--usr.sbin/bhyve/block_if.c21
-rw-r--r--usr.sbin/bhyve/block_if.h1
-rw-r--r--usr.sbin/bhyve/pci_ahci.c17
3 files changed, 36 insertions, 3 deletions
diff --git a/usr.sbin/bhyve/block_if.c b/usr.sbin/bhyve/block_if.c
index 8687e9a..5934006 100644
--- a/usr.sbin/bhyve/block_if.c
+++ b/usr.sbin/bhyve/block_if.c
@@ -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 char *ident)
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 char *ident)
*/
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 char *ident)
}
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 char *ident)
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)
{
diff --git a/usr.sbin/bhyve/block_if.h b/usr.sbin/bhyve/block_if.h
index c2c21f6..d1b7695 100644
--- a/usr.sbin/bhyve/block_if.h
+++ b/usr.sbin/bhyve/block_if.h
@@ -55,6 +55,7 @@ off_t blockif_size(struct blockif_ctxt *bc);
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);
diff --git a/usr.sbin/bhyve/pci_ahci.c b/usr.sbin/bhyve/pci_ahci.c
index 7db7ed5..87ad361 100644
--- a/usr.sbin/bhyve/pci_ahci.c
+++ b/usr.sbin/bhyve/pci_ahci.c
@@ -684,11 +684,14 @@ handle_identify(struct ahci_port *p, int slot, uint8_t *cfis)
} 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 slot, uint8_t *cfis)
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;
OpenPOWER on IntegriCloud