Add a call to synthesize a C/H/S value for block emulations
that require it (ahci). The algorithm used is from the VHD specification.
This commit is contained in:
parent
d634b1f709
commit
c4813fadf1
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=268638
@ -389,6 +389,55 @@ blockif_close(struct blockif_ctxt *bc)
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return virtual C/H/S values for a given block. Use the algorithm
|
||||
* outlined in the VHD specification to calculate values.
|
||||
*/
|
||||
void
|
||||
blockif_chs(struct blockif_ctxt *bc, uint16_t *c, uint8_t *h, uint8_t *s)
|
||||
{
|
||||
off_t sectors; /* total sectors of the block dev */
|
||||
off_t hcyl; /* cylinders times heads */
|
||||
uint16_t secpt; /* sectors per track */
|
||||
uint8_t heads;
|
||||
|
||||
assert(bc->bc_magic == BLOCKIF_SIG);
|
||||
|
||||
sectors = bc->bc_size / bc->bc_sectsz;
|
||||
|
||||
/* Clamp the size to the largest possible with CHS */
|
||||
if (sectors > 65535UL*16*255)
|
||||
sectors = 65535UL*16*255;
|
||||
|
||||
if (sectors >= 65536UL*16*63) {
|
||||
secpt = 255;
|
||||
heads = 16;
|
||||
hcyl = sectors / secpt;
|
||||
} else {
|
||||
secpt = 17;
|
||||
hcyl = sectors / secpt;
|
||||
heads = (hcyl + 1023) / 1024;
|
||||
|
||||
if (heads < 4)
|
||||
heads = 4;
|
||||
|
||||
if (hcyl >= (heads * 1024) || heads > 16) {
|
||||
secpt = 31;
|
||||
heads = 16;
|
||||
hcyl = sectors / secpt;
|
||||
}
|
||||
if (hcyl >= (heads * 1024)) {
|
||||
secpt = 63;
|
||||
heads = 16;
|
||||
hcyl = sectors / secpt;
|
||||
}
|
||||
}
|
||||
|
||||
*c = hcyl / heads;
|
||||
*h = heads;
|
||||
*s = secpt;
|
||||
}
|
||||
|
||||
/*
|
||||
* Accessors
|
||||
*/
|
||||
|
@ -52,6 +52,8 @@ struct blockif_req {
|
||||
struct blockif_ctxt;
|
||||
struct blockif_ctxt *blockif_open(const char *optstr, const char *ident);
|
||||
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);
|
||||
int blockif_queuesz(struct blockif_ctxt *bc);
|
||||
int blockif_is_ro(struct blockif_ctxt *bc);
|
||||
|
Loading…
Reference in New Issue
Block a user