summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/pc98/include/md_var.h12
-rw-r--r--sys/pc98/pc98/pc98_machdep.c38
2 files changed, 50 insertions, 0 deletions
diff --git a/sys/pc98/include/md_var.h b/sys/pc98/include/md_var.h
index 7d0fb7262651..7ca6f3cc8cf1 100644
--- a/sys/pc98/include/md_var.h
+++ b/sys/pc98/include/md_var.h
@@ -38,4 +38,16 @@
extern int need_pre_dma_flush;
extern int need_post_dma_flush;
+/*
+ * The ad driver maps the IDE disk's actual geometry to the firmware's
+ * notion of geometry. However, PC98 machines need to do something
+ * different sometimes, so override the hook so we can do so. We have to
+ * have a knowledge that a device_t is a struct device * here to avoid
+ * including too many things from this file.
+ */
+struct disk;
+struct device;
+void pc98_ad_firmware_geom_adjust(struct device *, struct disk *);
+#define ad_firmware_geom_adjust(dev, dsk) pc98_ad_firmware_geom_adjust(dev, dsk)
+
#endif /* !_PC98_INCLUDE_MD_VAR_H_ */
diff --git a/sys/pc98/pc98/pc98_machdep.c b/sys/pc98/pc98/pc98_machdep.c
index 2f2dfebbe43d..badf6a3ed735 100644
--- a/sys/pc98/pc98/pc98_machdep.c
+++ b/sys/pc98/pc98/pc98_machdep.c
@@ -38,6 +38,11 @@
#include <cam/cam.h>
#include <cam/cam_ccb.h>
+#include <sys/bio.h>
+#include <sys/bus.h>
+#include <sys/conf.h>
+#include <geom/geom_disk.h>
+#include <machine/md_var.h>
#include <pc98/pc98/pc98_machdep.h>
/*
@@ -191,3 +196,36 @@ scsi_da_bios_params(struct ccb_calc_geometry *ccg)
return (0);
}
+
+/*
+ * Get the geometry of the ATA HDD from the BIOS work area.
+ *
+ * XXX for now, we hack it
+ */
+void
+pc98_ad_firmware_geom_adjust(device_t dev, struct disk *disk)
+{
+ off_t totsec = disk->d_mediasize / disk->d_sectorsize;
+ off_t cyl = totsec / disk->d_fwsectors / disk->d_fwheads;
+
+ /*
+ * It is impossible to have more than 65535 cylendars, so if
+ * we have more then try to adjust. This is lame, but it is
+ * only POC.
+ */
+ if (cyl > 65355) {
+ if (totsec < 17*8*65535) {
+ disk->d_fwsectors = 17;
+ disk->d_fwheads = 8;
+ } else if (totsec < 63*16*65535) {
+ disk->d_fwsectors = 63;
+ disk->d_fwheads = 16;
+ } else if (totsec < 255*16*65535) {
+ disk->d_fwsectors = 255;
+ disk->d_fwheads = 16;
+ } else {
+ disk->d_fwsectors = 255;
+ disk->d_fwheads = 255;
+ }
+ }
+}