118334Speter/*
290087Sobrien * ----------------------------------------------------------------------------
3169699Skan * "THE BEER-WARE LICENSE" (Revision 42):
4169699Skan * <phk@FreeBSD.org> wrote this file.  As long as you retain this notice you
518334Speter * can do whatever you want with this stuff. If we meet some day, and you think
690087Sobrien * this stuff is worth it, you can buy me a beer in return.   Poul-Henning Kamp
718334Speter * ----------------------------------------------------------------------------
890087Sobrien */
990087Sobrien
1090087Sobrien#include <sys/cdefs.h>
1190087Sobrien__FBSDID("$FreeBSD$");
1218334Speter
1390087Sobrien#include <stdio.h>
1490087Sobrien#include <stdlib.h>
1590087Sobrien#include <unistd.h>
1690087Sobrien#include <fcntl.h>
1718334Speter#include <string.h>
1818334Speter#include <sys/types.h>
1990087Sobrien#include "libdisk.h"
20169699Skan
21169699Skanvoid
2218334SpeterSet_Bios_Geom(struct disk *disk, u_long cyl, u_long hd, u_long sect)
2318334Speter{
2418334Speter
2518334Speter	disk->bios_cyl = cyl;
2618334Speter	disk->bios_hd = hd;
2718334Speter	disk->bios_sect = sect;
2818334Speter}
2918334Speter
3018334Spetervoid
3118334SpeterSanitize_Bios_Geom(struct disk *disk)
3218334Speter{
3318334Speter	int sane;
3418334Speter
3518334Speter	sane = 1;
3618334Speter
3718334Speter	if (disk->bios_cyl >= 65536)
3818334Speter		sane = 0;
3918334Speter#ifdef PC98
4018334Speter	if (disk->bios_hd >= 256)
4118334Speter		sane = 0;
4218334Speter	if (disk->bios_sect >= 256)
4318334Speter		sane = 0;
4418334Speter#else
4590087Sobrien	if (disk->bios_hd > 256)
4690087Sobrien		sane = 0;
4718334Speter	if (disk->bios_sect > 63)
4818334Speter		sane = 0;
4950503Sobrien#endif
50132727Skan#if 0	/* Disable a check on a disk size.  It's too strict. */
51132727Skan	if (disk->bios_cyl * disk->bios_hd * disk->bios_sect !=
5218334Speter	    disk->chunks->size)
5318334Speter		sane = 0;
5418334Speter#endif
5590087Sobrien	if (sane)
5618334Speter		return;
5718334Speter
5818334Speter	/* First try something that IDE can handle */
5918334Speter	disk->bios_sect = 63;
6018334Speter	disk->bios_hd = 16;
6118334Speter	disk->bios_cyl = disk->chunks->size /
6218334Speter		(disk->bios_sect * disk->bios_hd);
6318334Speter
6418334Speter#ifdef PC98
6550503Sobrien	if (disk->bios_cyl < 65536)
6690087Sobrien#else
6750503Sobrien	if (disk->bios_cyl < 1024)
6850503Sobrien#endif
6952515Sobrien		return;
7090087Sobrien
7190087Sobrien	/* Hmm, try harder... */
7290087Sobrien	/* Assume standard SCSI parameter */
7390087Sobrien#ifdef PC98
74117404Skan	disk->bios_sect = 128;
75169699Skan	disk->bios_hd = 8;
76169699Skan#else
77169699Skan	disk->bios_hd = 255;
78169699Skan#endif
7918334Speter	disk->bios_cyl = disk->chunks->size /
8018334Speter		(disk->bios_sect * disk->bios_hd);
8190087Sobrien
8290087Sobrien#ifdef PC98
8318334Speter	if (disk->bios_cyl < 65536)
8418334Speter		return;
8550503Sobrien
8650503Sobrien	/* Assume UIDE-133/98-A Challenger BIOS 0.9821C parameter */
8750503Sobrien	disk->bios_sect = 255;
8850503Sobrien	disk->bios_hd = 16;
89132727Skan	disk->bios_cyl = disk->chunks->size /
90132727Skan		(disk->bios_sect * disk->bios_hd);
91132727Skan
92132727Skan	if (disk->bios_cyl < 65536)
93169699Skan		return;
94169699Skan
95169699Skan	/* BIG-na-Drive? */
96169699Skan	disk->bios_hd = 255;
9718334Speter	disk->bios_cyl = disk->chunks->size /
9818334Speter		(disk->bios_sect * disk->bios_hd);
9918334Speter#endif
10018334Speter}
10118334Speter
10218334Spetervoid
10318334SpeterAll_FreeBSD(struct disk *d, int force_all)
10418334Speter{
10518334Speter	struct chunk *c;
10618334Speter	int type;
10718334Speter
10818334Speter#ifdef PC98
10918334Speter	type = 0xc494;
11018334Speter#else
11118334Speter	type = 0xa5;
11218334Speter#endif
11350503Sobrien
11450503Sobrienagain:
11550503Sobrien	for (c = d->chunks->part; c; c = c->next)
11650503Sobrien		if (c->type != unused) {
117132727Skan			Delete_Chunk(d, c);
118132727Skan			goto again;
119132727Skan		}
120132727Skan	c = d->chunks;
121132727Skan	if (force_all) {
12218334Speter		Sanitize_Bios_Geom(d);
12390087Sobrien		Create_Chunk(d, c->offset, c->size, freebsd, type,
12490087Sobrien		    CHUNK_FORCE_ALL, "FreeBSD");
12518334Speter	} else {
12618334Speter		Create_Chunk(d, c->offset, c->size, freebsd, type, 0,
12718334Speter		    "FreeBSD");
12818334Speter	}
12918334Speter}
13018334Speter