svn commit: r184327 - head/sys/pc98/pc98
KATO Takenori
kato at FreeBSD.org
Mon Oct 27 01:40:14 PDT 2008
Author: kato
Date: Mon Oct 27 08:40:13 2008
New Revision: 184327
URL: http://svn.freebsd.org/changeset/base/184327
Log:
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
Modified:
head/sys/pc98/pc98/pc98_machdep.c
head/sys/pc98/pc98/pc98_machdep.h
Modified: head/sys/pc98/pc98/pc98_machdep.c
==============================================================================
--- head/sys/pc98/pc98/pc98_machdep.c Mon Oct 27 08:09:05 2008 (r184326)
+++ head/sys/pc98/pc98/pc98_machdep.c Mon Oct 27 08:40:13 2008 (r184327)
@@ -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_geom
}
/*
- * 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 de
}
}
}
+
+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);
+
+}
Modified: head/sys/pc98/pc98/pc98_machdep.h
==============================================================================
--- head/sys/pc98/pc98/pc98_machdep.h Mon Oct 27 08:09:05 2008 (r184326)
+++ head/sys/pc98/pc98/pc98_machdep.h Mon Oct 27 08:40:13 2008 (r184327)
@@ -85,6 +85,21 @@ extern unsigned char pc98_system_paramet
#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__ */
More information about the svn-src-all
mailing list