Report logical/physical sector sizes for virtual SATA disk.
MFC after: 2 weeks
This commit is contained in:
parent
297c4868dd
commit
94682383d9
@ -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, §sz)) {
|
||||
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user