summaryrefslogtreecommitdiffstats
path: root/sys/pc98
diff options
context:
space:
mode:
authorimp <imp@FreeBSD.org>2006-08-09 18:25:07 +0000
committerimp <imp@FreeBSD.org>2006-08-09 18:25:07 +0000
commit82de09b2c05916268aa4fc2161066b78c7d19118 (patch)
treea50879097e8a52eb800709d5fcfc79318848d99a /sys/pc98
parent0598f31308336f183158ca0b7f3cc024a72a7d7f (diff)
downloadFreeBSD-src-82de09b2c05916268aa4fc2161066b78c7d19118.zip
FreeBSD-src-82de09b2c05916268aa4fc2161066b78c7d19118.tar.gz
Add pc98 specific code to adjust the firmware geometry when it differs
from the actual geometry. This enables support of disks larger than ~120GB on pc98 boxes. They make great little network appliances. I've been using these changes for the past year or so on my network storage pc98 box :-).
Diffstat (limited to 'sys/pc98')
-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 7d0fb72..7ca6f3c 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 2f2dfeb..badf6a3 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;
+ }
+ }
+}
OpenPOWER on IntegriCloud