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 :-).
This commit is contained in:
Warner Losh 2006-08-09 18:25:07 +00:00
parent ab649fd4d2
commit c70759dcdd
2 changed files with 50 additions and 0 deletions

View file

@ -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_ */

View file

@ -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;
}
}
}