From c70759dcdd3d8abf746cb718dd606cb0fb18067a Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Wed, 9 Aug 2006 18:25:07 +0000 Subject: [PATCH] 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 :-). --- sys/pc98/include/md_var.h | 12 ++++++++++++ sys/pc98/pc98/pc98_machdep.c | 38 ++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/sys/pc98/include/md_var.h b/sys/pc98/include/md_var.h index 7d0fb726265..7ca6f3cc8cf 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 2f2dfebbe43..badf6a3ed73 100644 --- a/sys/pc98/pc98/pc98_machdep.c +++ b/sys/pc98/pc98/pc98_machdep.c @@ -38,6 +38,11 @@ #include #include +#include +#include +#include +#include +#include #include /* @@ -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; + } + } +}