summaryrefslogtreecommitdiffstats
path: root/sys/pc98
diff options
context:
space:
mode:
authorkato <kato@FreeBSD.org>2008-10-27 08:40:13 +0000
committerkato <kato@FreeBSD.org>2008-10-27 08:40:13 +0000
commit5b1802a644975116f659a38a856e52149303221a (patch)
treedc8200b7bf4b79ab1964fc0befd393d9d5611365 /sys/pc98
parent2bddeb51d2ea4f49f6d9b8533d381144dacce186 (diff)
downloadFreeBSD-src-5b1802a644975116f659a38a856e52149303221a.zip
FreeBSD-src-5b1802a644975116f659a38a856e52149303221a.tar.gz
Improved IDE HDD geometry adjustment. Previous code didn't work with
certain ATA-6 drives including CF cards. The IDE geometry of the PC98 is calculated from the drive capacity. In addition to the algorithm in NEC BIOS, a variety of algorithms are provided by 3'rd party boards and BIOS hacks. This change has implemented the three algorithms: IDE BIOS compatible mode, SCSI BIOS compatible mode and same way as the previous version. The tunable machdep.ad_geom_method selects the algorithm. I have been using this change for a year with CF cards. Reminded by: nyan
Diffstat (limited to 'sys/pc98')
-rw-r--r--sys/pc98/pc98/pc98_machdep.c104
-rw-r--r--sys/pc98/pc98/pc98_machdep.h15
2 files changed, 112 insertions, 7 deletions
diff --git a/sys/pc98/pc98/pc98_machdep.c b/sys/pc98/pc98/pc98_machdep.c
index badf6a3..31bb756 100644
--- a/sys/pc98/pc98/pc98_machdep.c
+++ b/sys/pc98/pc98/pc98_machdep.c
@@ -36,15 +36,23 @@
#include <sys/param.h>
#include <sys/systm.h>
-#include <cam/cam.h>
-#include <cam/cam_ccb.h>
#include <sys/bio.h>
#include <sys/bus.h>
#include <sys/conf.h>
+#include <sys/kernel.h>
+#include <sys/sysctl.h>
+#include <cam/cam.h>
+#include <cam/cam_ccb.h>
#include <geom/geom_disk.h>
#include <machine/md_var.h>
#include <pc98/pc98/pc98_machdep.h>
+static int ad_geom_method = AD_GEOM_ADJUST_COMPATIDE;
+
+TUNABLE_INT("machdep.ad_geom_method", &ad_geom_method);
+SYSCTL_INT(_machdep, OID_AUTO, ad_geom_method, CTLFLAG_RW, &ad_geom_method, 0,
+ "IDE disk geometry conversion method");
+
/*
* Initialize DMA controller
*/
@@ -198,12 +206,62 @@ scsi_da_bios_params(struct ccb_calc_geometry *ccg)
}
/*
- * Get the geometry of the ATA HDD from the BIOS work area.
- *
- * XXX for now, we hack it
+ * Adjust the geometry of the IDE HDD.
*/
-void
-pc98_ad_firmware_geom_adjust(device_t dev, struct disk *disk)
+
+/* IDE BIOS compatible mode. */
+static void
+pc98_ad_geom_adjust_idebios(struct disk *disk)
+{
+
+ if (disk->d_mediasize < MEDIASIZE_4_3G) {
+ disk->d_fwsectors = 17;
+ disk->d_fwheads = 8;
+ } else if (disk->d_mediasize < MEDIASIZE_29_5G) {
+ disk->d_fwsectors = 63;
+ if (disk->d_fwheads != 15) /* Allow 15H63S. */
+ disk->d_fwheads = 16;
+ } else if (disk->d_mediasize < MEDIASIZE_31_5G) {
+ disk->d_fwsectors = 63;
+ disk->d_fwheads = 16;
+ } else if (disk->d_mediasize < MEDIASIZE_127G) {
+ disk->d_fwsectors = 255;
+ disk->d_fwheads = 16;
+ } else {
+ /* XXX */
+ disk->d_fwsectors = 255;
+ disk->d_fwheads = 255;
+ }
+}
+
+/* SCSI BIOS compatible mode. */
+static void
+pc98_ad_geom_adjust_scsibios(struct disk *disk)
+{
+
+ if (disk->d_mediasize < MEDIASIZE_8G) {
+ disk->d_fwsectors = 32;
+ disk->d_fwheads = 8;
+ } else if (disk->d_mediasize < MEDIASIZE_32G) {
+ disk->d_fwsectors = 128;
+ disk->d_fwheads = 8;
+ } else if (disk->d_mediasize < MEDIASIZE_60G) {
+ /* Compatible with IFC-USP 1.2. */
+ disk->d_fwsectors = 128;
+ disk->d_fwheads = 15;
+ } else if (disk->d_mediasize < MEDIASIZE_120G) {
+ disk->d_fwsectors = 255;
+ disk->d_fwheads = 15;
+ } else {
+ /* XXX */
+ disk->d_fwsectors = 255;
+ disk->d_fwheads = 255;
+ }
+}
+
+/* Compatible with the revision 1.28. */
+static void
+pc98_ad_geom_adjust_cyl16bit(struct disk *disk)
{
off_t totsec = disk->d_mediasize / disk->d_sectorsize;
off_t cyl = totsec / disk->d_fwsectors / disk->d_fwheads;
@@ -229,3 +287,35 @@ pc98_ad_firmware_geom_adjust(device_t dev, struct disk *disk)
}
}
}
+
+void
+pc98_ad_firmware_geom_adjust(device_t dev, struct disk *disk)
+{
+ u_int oldsectors, oldheads;
+
+ oldsectors = disk->d_fwsectors;
+ oldheads = disk->d_fwheads;
+
+ switch (ad_geom_method) {
+ case AD_GEOM_ADJUST_COMPATIDE:
+ pc98_ad_geom_adjust_idebios(disk);
+ break;
+ case AD_GEOM_ADJUST_COMPATSCSI:
+ pc98_ad_geom_adjust_scsibios(disk);
+ break;
+ case AD_GEOM_ADJUST_COMPATCYL16:
+ pc98_ad_geom_adjust_cyl16bit(disk);
+ break;
+ default:
+ /* Do nothing. */
+ break;
+ }
+
+ if (bootverbose &&
+ (oldsectors != disk->d_fwsectors || oldheads != disk->d_fwheads))
+ device_printf(dev,
+ "geometry adjusted from [%dH/%dS] to [%dH/%dS]\n",
+ oldheads, oldsectors,
+ disk->d_fwheads, disk->d_fwsectors);
+
+}
diff --git a/sys/pc98/pc98/pc98_machdep.h b/sys/pc98/pc98/pc98_machdep.h
index ffd4ba8..6113f14 100644
--- a/sys/pc98/pc98/pc98_machdep.h
+++ b/sys/pc98/pc98/pc98_machdep.h
@@ -85,6 +85,21 @@ extern unsigned char pc98_system_parameter[]; /* in locore.c */
#define EPSON_PC486_SR 0x38
#define EPSON_PC486_HA 0x3b
+/* IDE HDD geometry conversion. */
+#define AD_GEOM_ADJUST_NONE 0 /* Do nothing. */
+#define AD_GEOM_ADJUST_COMPATIDE 1 /* PC-98 IDE BIOS. */
+#define AD_GEOM_ADJUST_COMPATSCSI 2 /* PC-98 SCSI. */
+#define AD_GEOM_ADJUST_COMPATCYL16 100 /* Compat Rev. 1.28. */
+
+#define MEDIASIZE_4_3G (4351LL * 1024LL * 1024LL) /* 4351M */
+#define MEDIASIZE_8G (8192LL * 1024LL * 1024LL) /* 8192M */
+#define MEDIASIZE_29_5G (30239LL * 1024LL * 1024LL) /* 30239M */
+#define MEDIASIZE_31_5G (32255LL * 1024 * 1024) /* 32255M */
+#define MEDIASIZE_32G (32768LL * 1024LL * 1024LL) /* 32768M */
+#define MEDIASIZE_60G (61440LL * 1024LL * 1024LL) /* 61440M */
+#define MEDIASIZE_120G (122400LL * 1024LL * 1024LL) /* 122400M */
+#define MEDIASIZE_127G (130558LL * 1024LL * 1024LL) /* 130558M */
+
#endif /* _KERNEL */
#endif /* __PC98_PC98_PC98_MACHDEP_H__ */
OpenPOWER on IntegriCloud