Author: grehan
Date: Tue Jul 15 00:25:54 2014
New Revision: 268638
URL: http://svnweb.freebsd.org/changeset/base/268638

Log:
  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.

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

Modified: head/usr.sbin/bhyve/block_if.c
==============================================================================
--- head/usr.sbin/bhyve/block_if.c      Mon Jul 14 23:25:29 2014        
(r268637)
+++ head/usr.sbin/bhyve/block_if.c      Tue Jul 15 00:25:54 2014        
(r268638)
@@ -390,6 +390,55 @@ blockif_close(struct blockif_ctxt *bc)
 }
 
 /*
+ * 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
  */
 off_t

Modified: head/usr.sbin/bhyve/block_if.h
==============================================================================
--- head/usr.sbin/bhyve/block_if.h      Mon Jul 14 23:25:29 2014        
(r268637)
+++ head/usr.sbin/bhyve/block_if.h      Tue Jul 15 00:25:54 2014        
(r268638)
@@ -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);
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to