xref: /openbsd/sbin/fdisk/part.c (revision 6bf2f4b9)
1*6bf2f4b9Smiod /*	$OpenBSD: part.c,v 1.25 2001/11/07 01:27:33 miod Exp $	*/
2a1705421Sweingart 
3a1705421Sweingart /*
4a1705421Sweingart  * Copyright (c) 1997 Tobias Weingartner
5a1705421Sweingart  * All rights reserved.
6a1705421Sweingart  *
7a1705421Sweingart  * Redistribution and use in source and binary forms, with or without
8a1705421Sweingart  * modification, are permitted provided that the following conditions
9a1705421Sweingart  * are met:
10a1705421Sweingart  * 1. Redistributions of source code must retain the above copyright
11a1705421Sweingart  *    notice, this list of conditions and the following disclaimer.
12a1705421Sweingart  * 2. Redistributions in binary form must reproduce the above copyright
13a1705421Sweingart  *    notice, this list of conditions and the following disclaimer in the
14a1705421Sweingart  *    documentation and/or other materials provided with the distribution.
15a1705421Sweingart  * 3. All advertising materials mentioning features or use of this software
16a1705421Sweingart  *    must display the following acknowledgement:
17a1705421Sweingart  *    This product includes software developed by Tobias Weingartner.
18a1705421Sweingart  * 4. The name of the author may not be used to endorse or promote products
19a1705421Sweingart  *    derived from this software without specific prior written permission.
20a1705421Sweingart  *
21a1705421Sweingart  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22a1705421Sweingart  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23a1705421Sweingart  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24a1705421Sweingart  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25a1705421Sweingart  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26a1705421Sweingart  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27a1705421Sweingart  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28a1705421Sweingart  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29a1705421Sweingart  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30a1705421Sweingart  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31a1705421Sweingart  */
32a1705421Sweingart 
33a1705421Sweingart #include <err.h>
34a1705421Sweingart #include <util.h>
35a1705421Sweingart #include <stdio.h>
36184a329bSmillert #include <string.h>
37a1705421Sweingart #include <unistd.h>
38a1705421Sweingart #include <sys/fcntl.h>
39a1705421Sweingart #include <sys/types.h>
40a1705421Sweingart #include <sys/stat.h>
41a1705421Sweingart #include <sys/disklabel.h>
42a1705421Sweingart #include <machine/param.h>
43a1705421Sweingart #include "disk.h"
44a1705421Sweingart #include "misc.h"
45a1705421Sweingart #include "mbr.h"
46a1705421Sweingart 
47a1705421Sweingart 
486c2b1c19Smickey static const struct part_type {
49a1705421Sweingart 	int	type;
506c2b1c19Smickey 	char	sname[14];
514b464610Sderaadt 	char	*lname;
52a1705421Sweingart } part_types[] = {
534b464610Sderaadt 	{ 0x00, "unused      ", "unused"},
544b464610Sderaadt 	{ 0x01, "DOS FAT-12  ", "Primary DOS with 12 bit FAT"},
554b464610Sderaadt 	{ 0x02, "XENIX /     ", "XENIX / filesystem"},
564b464610Sderaadt 	{ 0x03, "XENIX /usr  ", "XENIX /usr filesystem"},
574b464610Sderaadt 	{ 0x04, "DOS FAT-16  ", "Primary DOS with 16 bit FAT"},
584b464610Sderaadt 	{ 0x05, "Extended DOS", "Extended DOS"},
594b464610Sderaadt 	{ 0x06, "DOS > 32MB  ", "Primary 'big' DOS (> 32MB)"},
60f3f2107eSderaadt 	{ 0x07, "HPFS/QNX/AUX", "OS/2 HPFS, QNX-2 or Advanced UNIX"},
614b464610Sderaadt 	{ 0x08, "AIX fs      ", "AIX filesystem"},
624b464610Sderaadt 	{ 0x09, "AIX/Coherent", "AIX boot partition or Coherent"},
634b464610Sderaadt 	{ 0x0A, "OS/2 Bootmgr", "OS/2 Boot Manager or OPUS"},
644b464610Sderaadt 	{ 0x0B, "Win95 FAT-32", "Primary Win95 w/ 32-bit FAT"},
65c3e3230dSderaadt 	{ 0x0C, "Win95 FAT32L", "Primary Win95 w/ 32-bit FAT LBA-mapped"},
664b464610Sderaadt 	{ 0x0E, "DOS FAT-16  ", "Primary DOS w/ 16-bit FAT, CHS-mapped"},
67c3e3230dSderaadt 	{ 0x0F, "Extended LBA", "Extended DOS LBA-mapped"},
684b464610Sderaadt 	{ 0x10, "OPUS        ", "OPUS"},
6992ee32bfSkjell 	{ 0x11, "OS/2 hidden ", "OS/2 BM: hidden DOS 12-bit FAT"},
704b464610Sderaadt 	{ 0x12, "Compaq Diag.", "Compaq Diagnostics"},
7192ee32bfSkjell 	{ 0x14, "OS/2 hidden ", "OS/2 BM: hidden DOS 16-bit FAT <32M or Novell DOS 7.0 bug"},
7292ee32bfSkjell 	{ 0x16, "OS/2 hidden ", "OS/2 BM: hidden DOS 16-bit FAT >=32M"},
7392ee32bfSkjell 	{ 0x17, "OS/2 hidden ", "OS/2 BM: hidden IFS"},
7492ee32bfSkjell 	{ 0x18, "AST swap    ", "AST Windows swapfile"},
7592ee32bfSkjell 	{ 0x19, "Willowtech  ", "Willowtech Photon coS"},
7692ee32bfSkjell 	{ 0x20, "Willowsoft  ", "Willowsoft OFS1"},
7792ee32bfSkjell 	{ 0x24, "NEC DOS     ", "NEC DOS"},
7892ee32bfSkjell 	{ 0x38, "Theos       ", "Theos"},
79a34f1fa7Smarkus 	{ 0x39, "Plan 9      ",	"Plan 9"},
8092ee32bfSkjell 	{ 0x40, "VENIX 286   ", "VENIX 286 or LynxOS"},
8192ee32bfSkjell 	{ 0x41, "Lin/Minux DR", "Linux/MINIX (sharing disk with DRDOS) or Personal RISC boot"},
8292ee32bfSkjell 	{ 0x42, "LinuxSwap DR", "SFS or Linux swap (sharing disk with DRDOS)"},
8392ee32bfSkjell 	{ 0x43, "Linux DR    ", "Linux native (sharing disk with DRDOS)"},
8492ee32bfSkjell 	{ 0x4D, "QNX 4.2 Pri ", "QNX 4.2 Primary"},
8592ee32bfSkjell 	{ 0x4E, "QNX 4.2 Sec ", "QNX 4.2 Secondary"},
8692ee32bfSkjell 	{ 0x4F, "QNX 4.2 Ter ", "QNX 4.2 Tertiary"},
8792ee32bfSkjell 	{ 0x50, "DM          ", "DM (disk manager)"},
8892ee32bfSkjell 	{ 0x51, "DM          ", "DM6 Aux1 (or Novell)"},
894b464610Sderaadt 	{ 0x52, "CP/M or SysV", "CP/M or Microport SysV/AT"},
9092ee32bfSkjell 	{ 0x53, "DM          ", "DM6 Aux3"},
914b464610Sderaadt 	{ 0x54, "Ontrack     ", "Ontrack"},
9292ee32bfSkjell 	{ 0x55, "EZ-Drive    ", "EZ-Drive (disk manager)"},
9392ee32bfSkjell 	{ 0x56, "Golden Bow  ", "Golden Bow (disk manager)"},
9492ee32bfSkjell 	{ 0x5C, "Priam       ", "Priam Edisk (disk manager)"},
9592ee32bfSkjell 	{ 0x61, "SpeedStor   ", "SpeedStor"},
964b464610Sderaadt 	{ 0x63, "ISC, HURD, *", "ISC, System V/386, GNU HURD or Mach"},
974b464610Sderaadt 	{ 0x64, "Netware 2.xx", "Novell Netware 2.xx"},
984b464610Sderaadt 	{ 0x65, "Netware 3.xx", "Novell Netware 3.xx"},
9992ee32bfSkjell 	{ 0x66, "Netware 386 ", "Novell 386 Netware"},
10092ee32bfSkjell 	{ 0x67, "Novell      ", "Novell"},
10192ee32bfSkjell 	{ 0x68, "Novell      ", "Novell"},
10292ee32bfSkjell 	{ 0x69, "Novell      ", "Novell"},
10392ee32bfSkjell 	{ 0x70, "DiskSecure  ", "DiskSecure Multi-Boot"},
1044b464610Sderaadt 	{ 0x75, "PCIX        ", "PCIX"},
1054b464610Sderaadt 	{ 0x80, "Minix (old) ", "Minix 1.1 ... 1.4a"},
1064b464610Sderaadt 	{ 0x81, "Minix (new) ", "Minix 1.4b ... 1.5.10"},
1074b464610Sderaadt 	{ 0x82, "Linux swap  ", "Linux swap"},
1084b464610Sderaadt 	{ 0x83, "Linux files*", "Linux filesystem"},
1094b464610Sderaadt 	{ 0x93, "Amoeba file*", "Amoeba filesystem"},
1104b464610Sderaadt 	{ 0x94, "Amoeba BBT  ", "Amoeba bad block table"},
11192ee32bfSkjell 	{ 0x84, "OS/2 hidden ", "OS/2 hidden C: drive"},
11292ee32bfSkjell 	{ 0x85, "Linux ext.  ", "Linux extended"},
11392ee32bfSkjell 	{ 0x86, "NT FAT VS   ", "NT FAT volume set"},
11492ee32bfSkjell 	{ 0x87, "NTFS VS     ", "NTFS volume set or HPFS mirrored"},
11592ee32bfSkjell 	{ 0x93, "Amoeba FS   ", "Amoeba filesystem"},
11692ee32bfSkjell 	{ 0x94, "Amoeba BBT  ", "Amoeba bad block table"},
11792ee32bfSkjell 	{ 0x99, "Mylex       ", "Mylex EISA SCSI"},
11892ee32bfSkjell 	{ 0x9F, "BSDI        ", "BSDI BSD/OS"},
1193addffc7Sian 	{ 0xA0, "NotebookSave", "Phoenix NoteBIOS save-to-disk"},
12058fe3b3aSderaadt 	{ 0xA5, "FreeBSD     ",	"FreeBSD"},
1214b464610Sderaadt 	{ 0xA6, "OpenBSD     ", "OpenBSD"},
1224b464610Sderaadt 	{ 0xA7, "NEXTSTEP    ", "NEXTSTEP"},
123*6bf2f4b9Smiod 	{ 0xA8, "MacOS X     ",	"MacOS X main partition"},
12458fe3b3aSderaadt 	{ 0xA9, "NetBSD      ",	"NetBSD"},
125*6bf2f4b9Smiod 	{ 0xAB, "MacOS X boot",	"MacOS X boot partition"},
1264b464610Sderaadt 	{ 0xB7, "BSDI filesy*", "BSDI BSD/386 filesystem"},
1274b464610Sderaadt 	{ 0xB8, "BSDI swap   ", "BSDI BSD/386 swap"},
12892ee32bfSkjell 	{ 0xC0, "CTOS        ", "CTOS"},
12992ee32bfSkjell 	{ 0xC1, "DRDOSs FAT12", "DRDOS/sec (FAT-12)"},
13092ee32bfSkjell 	{ 0xC4, "DRDOSs < 32M", "DRDOS/sec (FAT-16, < 32M)"},
13192ee32bfSkjell 	{ 0xC6, "DRDOSs >=32M", "DRDOS/sec (FAT-16, >= 32M)"},
13292ee32bfSkjell 	{ 0xC7, "HPFS Disbled", "Syrinx (Cyrnix?) or HPFS disabled"},
1334b464610Sderaadt 	{ 0xDB, "CPM/C.DOS/C*", "Concurrent CPM or C.DOS or CTOS"},
13492ee32bfSkjell 	{ 0xE1, "SpeedStor   ", "DOS access or SpeedStor 12-bit FAT extended partition"},
13592ee32bfSkjell 	{ 0xE3, "SpeedStor   ", "DOS R/O or SpeedStor or Storage Dimensions"},
13692ee32bfSkjell 	{ 0xE4, "SpeedStor   ", "SpeedStor 16-bit FAT extended partition < 1024 cyl."},
137092b495fSderaadt 	{ 0xEB, "BeOS/i386   ", "BeOS for Intel"},
13892ee32bfSkjell 	{ 0xF1, "SpeedStor   ", "SpeedStor or Storage Dimensions"},
1394b464610Sderaadt 	{ 0xF2, "DOS 3.3+ Sec", "DOS 3.3+ Secondary"},
14092ee32bfSkjell 	{ 0xF4, "SpeedStor   ", "SpeedStor >1024 cyl. or LANstep or IBM PS/2 IML"},
14192ee32bfSkjell 	{ 0xFF, "Xenix BBT   ", "Xenix Bad Block Table"},
142a1705421Sweingart };
143a1705421Sweingart 
1444b464610Sderaadt void
1454b464610Sderaadt PRT_printall()
1464b464610Sderaadt {
147d20bdfc6Skrw 	int i, idrows;
148d20bdfc6Skrw 
149d20bdfc6Skrw         idrows = ((sizeof(part_types)/sizeof(struct part_type))+3)/4;
1504b464610Sderaadt 
151c2ad5584Sderaadt 	printf("Choose from the following Partition id values:\n");
152d20bdfc6Skrw 	for (i = 0; i < idrows; i++) {
153d20bdfc6Skrw 		printf("%02X %s   %02X %s   %02X %s"
154d20bdfc6Skrw                       , part_types[i         ].type, part_types[i         ].sname
155d20bdfc6Skrw                       , part_types[i+idrows  ].type, part_types[i+idrows  ].sname
156d20bdfc6Skrw                       , part_types[i+idrows*2].type, part_types[i+idrows*2].sname
157d20bdfc6Skrw                       );
158d20bdfc6Skrw                 if ((i+idrows*3) < (sizeof(part_types)/sizeof(struct part_type))) {
159d20bdfc6Skrw 		       printf("   %02X %s\n"
160d20bdfc6Skrw                              , part_types[i+idrows*3].type, part_types[i+idrows*3].sname );
1614b464610Sderaadt                 }
162d20bdfc6Skrw 		else
1634b464610Sderaadt 		        printf( "\n" );
1644b464610Sderaadt 	}
165d20bdfc6Skrw }
166a1705421Sweingart 
1676c2b1c19Smickey const char *
168a1705421Sweingart PRT_ascii_id(id)
169a1705421Sweingart 	int id;
170a1705421Sweingart {
171a1705421Sweingart 	static char unknown[] = "<Unknown ID>";
172a1705421Sweingart 	int i;
173a1705421Sweingart 
174a1705421Sweingart 	for (i = 0; i < sizeof(part_types)/sizeof(struct part_type); i++) {
175a1705421Sweingart 		if (part_types[i].type == id)
1764b464610Sderaadt 			return (part_types[i].sname);
177a1705421Sweingart 	}
178a1705421Sweingart 
179a1705421Sweingart 	return (unknown);
180a1705421Sweingart }
181a1705421Sweingart 
182a1705421Sweingart void
1830d5049c6Smickey PRT_parse(disk, prt, offset, reloff, partn, pn)
1844ed7cd7eSrahnds 	disk_t *disk;
185a1705421Sweingart 	void *prt;
186ca2e86e1Sprovos 	off_t offset;
187ca2e86e1Sprovos 	off_t reloff;
188a1705421Sweingart 	prt_t *partn;
1890d5049c6Smickey 	int pn;
190a1705421Sweingart {
191a1705421Sweingart 	unsigned char *p = prt;
192ca2e86e1Sprovos 	off_t off;
193a1705421Sweingart 
194a1705421Sweingart 	partn->flag = *p++;
195a1705421Sweingart 	partn->shead = *p++;
196ca2e86e1Sprovos 
197a1705421Sweingart 	partn->ssect = (*p) & 0x3F;
198a1705421Sweingart 	partn->scyl = ((*p << 2) & 0xFF00) | (*(p+1));
199a1705421Sweingart 	p += 2;
200a1705421Sweingart 
201a1705421Sweingart 	partn->id = *p++;
202a1705421Sweingart 	partn->ehead = *p++;
203a1705421Sweingart 	partn->esect = (*p) & 0x3F;
204a1705421Sweingart 	partn->ecyl = ((*p << 2) & 0xFF00) | (*(p+1));
205a1705421Sweingart 	p += 2;
206a1705421Sweingart 
207c3e3230dSderaadt 	if ((partn->id == DOSPTYP_EXTEND) || (partn->id == DOSPTYP_EXTENDL))
208c3e3230dSderaadt 		off = reloff;
209c3e3230dSderaadt 	else
210c3e3230dSderaadt 		off = offset;
211ca2e86e1Sprovos 
212ca2e86e1Sprovos 	partn->bs = getlong(p) + off;
213a1705421Sweingart 	partn->ns = getlong(p+4);
2144ed7cd7eSrahnds 
2150d5049c6Smickey 	PRT_fix_CHS(disk, partn, pn);
2164ed7cd7eSrahnds }
217a1705421Sweingart 
2184ed7cd7eSrahnds int
2194ed7cd7eSrahnds PRT_check_chs(partn)
2204ed7cd7eSrahnds 	prt_t *partn;
2214ed7cd7eSrahnds {
2224ed7cd7eSrahnds 	if ( (partn->shead > 255) ||
2234ed7cd7eSrahnds 		(partn->ssect >63) ||
2244ed7cd7eSrahnds 		(partn->scyl > 1023) ||
2254ed7cd7eSrahnds 		(partn->ehead >255) ||
2264ed7cd7eSrahnds 		(partn->esect >63) ||
2274ed7cd7eSrahnds 		(partn->ecyl > 1023) )
2284ed7cd7eSrahnds 	{
2294ed7cd7eSrahnds 		return 0;
2304ed7cd7eSrahnds 	}
2314ed7cd7eSrahnds 	return 1;
2324ed7cd7eSrahnds }
233a1705421Sweingart void
234ca2e86e1Sprovos PRT_make(partn, offset, reloff, prt)
235a1705421Sweingart 	prt_t *partn;
236ca2e86e1Sprovos 	off_t offset;
237ca2e86e1Sprovos 	off_t reloff;
238a1705421Sweingart 	void *prt;
239a1705421Sweingart {
240a1705421Sweingart 	unsigned char *p = prt;
241c3e3230dSderaadt 	prt_t tmp;
242c3e3230dSderaadt 	off_t off;
243c3e3230dSderaadt 
244c3e3230dSderaadt 	tmp.shead = partn->shead;
245c3e3230dSderaadt 	tmp.ssect = partn->ssect;
246eb4cb19dSkjell 	tmp.scyl = (partn->scyl > 1023)? 1023: partn->scyl;
247c3e3230dSderaadt 	tmp.ehead = partn->ehead;
248c3e3230dSderaadt 	tmp.esect = partn->ssect;
249eb4cb19dSkjell 	tmp.ecyl = (partn->ecyl > 1023)? 1023: partn->ecyl;
250c3e3230dSderaadt 	if (!PRT_check_chs(partn) && PRT_check_chs(&tmp)) {
251c3e3230dSderaadt 		partn->shead = tmp.shead;
252c3e3230dSderaadt 		partn->ssect = tmp.ssect;
253c3e3230dSderaadt 		partn->scyl = tmp.scyl;
254c3e3230dSderaadt 		partn->ehead = tmp.ehead;
255c3e3230dSderaadt 		partn->esect = tmp.esect;
256c3e3230dSderaadt 		partn->ecyl = tmp.ecyl;
257c3e3230dSderaadt 		printf("Cylinder values are modified to fit in CHS.\n");
258c3e3230dSderaadt 	}
259c3e3230dSderaadt 	if ((partn->id == DOSPTYP_EXTEND) || (partn->id == DOSPTYP_EXTENDL))
260c3e3230dSderaadt 		off = reloff;
261c3e3230dSderaadt 	else
262c3e3230dSderaadt 		off = offset;
263a1705421Sweingart 
2644ed7cd7eSrahnds 	if (PRT_check_chs(partn)) {
265a1705421Sweingart 		*p++ = partn->flag & 0xFF;
2664ed7cd7eSrahnds 
267a1705421Sweingart 		*p++ = partn->shead & 0xFF;
268a1705421Sweingart 		*p++ = (partn->ssect & 0x3F) | ((partn->scyl & 0x300) >> 2);
269a1705421Sweingart 		*p++ = partn->scyl & 0xFF;
270a1705421Sweingart 
271a1705421Sweingart 		*p++ = partn->id & 0xFF;
272a1705421Sweingart 
273a1705421Sweingart 		*p++ = partn->ehead & 0xFF;
274a1705421Sweingart 		*p++ = (partn->esect & 0x3F) | ((partn->ecyl & 0x300) >> 2);
275a1705421Sweingart 		*p++ = partn->ecyl & 0xFF;
2764ed7cd7eSrahnds 	} else {
2774ed7cd7eSrahnds 		/* should this really keep flag, id and set others to 0xff? */
2784ed7cd7eSrahnds 		*p++ = partn->flag & 0xFF;
2794ed7cd7eSrahnds 		*p++ = 0xFF;
2804ed7cd7eSrahnds 		*p++ = 0xFF;
2814ed7cd7eSrahnds 		*p++ = 0xFF;
2824ed7cd7eSrahnds 		*p++ = partn->id & 0xFF;
2834ed7cd7eSrahnds 		*p++ = 0xFF;
2844ed7cd7eSrahnds 		*p++ = 0xFF;
2854ed7cd7eSrahnds 		*p++ = 0xFF;
2864ed7cd7eSrahnds 		printf("Warning CHS values out of bounds only saving LBA values\n");
2874ed7cd7eSrahnds 	}
288a1705421Sweingart 
289ca2e86e1Sprovos 	putlong(p, partn->bs - off);
290a1705421Sweingart 	putlong(p+4, partn->ns);
291a1705421Sweingart }
292a1705421Sweingart 
293a1705421Sweingart void
294a1705421Sweingart PRT_print(num, partn)
295a1705421Sweingart 	int num;
296a1705421Sweingart 	prt_t *partn;
297a1705421Sweingart {
298a1705421Sweingart 
299a1705421Sweingart 	if (partn == NULL) {
300a1705421Sweingart 		printf("         Starting       Ending\n");
301a1705421Sweingart 		printf(" #: id  cyl  hd sec -  cyl  hd sec [     start -       size]\n");
3026c2b1c19Smickey 		printf("------------------------------------------------------------------------\n");
303a1705421Sweingart 	} else {
3046c2b1c19Smickey 		printf("%c%1d: %.2X %4d %3d %3d - %4d %3d %3d [%10d - %10d] %s\n",
305a1705421Sweingart 			(partn->flag == 0x80)?'*':' ',
306a1705421Sweingart 			num, partn->id,
307a1705421Sweingart 			partn->scyl, partn->shead, partn->ssect,
308a1705421Sweingart 			partn->ecyl, partn->ehead, partn->esect,
309a1705421Sweingart 			partn->bs, partn->ns,
310a1705421Sweingart 			PRT_ascii_id(partn->id));
311a1705421Sweingart 	}
312a1705421Sweingart }
313a1705421Sweingart 
314a1705421Sweingart void
3150d5049c6Smickey PRT_fix_BN(disk, part, pn)
316a1705421Sweingart 	disk_t *disk;
317a1705421Sweingart 	prt_t *part;
3180d5049c6Smickey 	int pn;
319a1705421Sweingart {
320a1705421Sweingart 	int spt, tpc, spc;
321a1705421Sweingart 	int start = 0;
322a1705421Sweingart 	int end = 0;
323a1705421Sweingart 
324eb4cb19dSkjell 	/* Zero out entry if not used */
325eb4cb19dSkjell 	if (part->id == DOSPTYP_UNUSED ) {
326eb4cb19dSkjell 		memset(part, 0, sizeof(*part));
327eb4cb19dSkjell 		return;
328eb4cb19dSkjell 	}
329eb4cb19dSkjell 
330a1705421Sweingart 	/* Disk metrics */
3314b464610Sderaadt 	spt = disk->real->sectors;
3324b464610Sderaadt 	tpc = disk->real->heads;
333a1705421Sweingart 	spc = spt * tpc;
334a1705421Sweingart 
335a1705421Sweingart 	start += part->scyl * spc;
336a1705421Sweingart 	start += part->shead * spt;
337a1705421Sweingart 	start += part->ssect - 1;
338a1705421Sweingart 
339a1705421Sweingart 	end += part->ecyl * spc;
340a1705421Sweingart 	end += part->ehead * spt;
341a1705421Sweingart 	end += part->esect - 1;
342a1705421Sweingart 
343a1705421Sweingart 	/* XXX - Should handle this... */
344a1705421Sweingart 	if (start > end)
3450d5049c6Smickey 		warn("Start of partition #%d after end!", pn);
346a1705421Sweingart 
347a1705421Sweingart 	part->bs = start;
348a1705421Sweingart 	part->ns = (end - start) + 1;
349a1705421Sweingart }
350a1705421Sweingart 
351a1705421Sweingart void
3520d5049c6Smickey PRT_fix_CHS(disk, part, pn)
353a1705421Sweingart 	disk_t *disk;
354a1705421Sweingart 	prt_t *part;
3550d5049c6Smickey 	int pn;
356a1705421Sweingart {
357a1705421Sweingart 	int spt, tpc, spc;
358a1705421Sweingart 	int start, end, size;
359a1705421Sweingart 	int cyl, head, sect;
360a1705421Sweingart 
361eb4cb19dSkjell 	/* Zero out entry if not used */
362eb4cb19dSkjell 	if (part->id == DOSPTYP_UNUSED ) {
363eb4cb19dSkjell 		memset(part, 0, sizeof(*part));
364eb4cb19dSkjell 		return;
365eb4cb19dSkjell 	}
366eb4cb19dSkjell 
367a1705421Sweingart 	/* Disk metrics */
3684b464610Sderaadt 	spt = disk->real->sectors;
3694b464610Sderaadt 	tpc = disk->real->heads;
370a1705421Sweingart 	spc = spt * tpc;
371a1705421Sweingart 
372a1705421Sweingart 	start = part->bs;
373a1705421Sweingart 	size = part->ns;
374a1705421Sweingart 	end = (start + size) - 1;
375a1705421Sweingart 
376a1705421Sweingart 	/* Figure out starting CHS values */
377a1705421Sweingart 	cyl = (start / spc); start -= (cyl * spc);
378a1705421Sweingart 	head = (start / spt); start -= (head * spt);
379a1705421Sweingart 	sect = (start + 1);
380a1705421Sweingart 
381c3e3230dSderaadt 	if (cyl > 1023) {
382c3e3230dSderaadt 		cyl = 1023;
3830d5049c6Smickey 		printf("Only LBA values are valid in starting cylinder for partition #%d.\n", pn);
384c3e3230dSderaadt 	}
385a1705421Sweingart 	part->scyl = cyl;
386a1705421Sweingart 	part->shead = head;
387a1705421Sweingart 	part->ssect = sect;
388a1705421Sweingart 
389a1705421Sweingart 	/* Figure out ending CHS values */
390a1705421Sweingart 	cyl = (end / spc); end -= (cyl * spc);
391a1705421Sweingart 	head = (end / spt); end -= (head * spt);
392a1705421Sweingart 	sect = (end + 1);
393a1705421Sweingart 
394c3e3230dSderaadt 	if (cyl > 1023) {
395c3e3230dSderaadt 		cyl = 1023;
3960d5049c6Smickey 		printf("Only LBA values are valid in ending cylinder for partition #%d.\n", pn);
397c3e3230dSderaadt 	}
398a1705421Sweingart 	part->ecyl = cyl;
399a1705421Sweingart 	part->ehead = head;
400a1705421Sweingart 	part->esect = sect;
401a1705421Sweingart }
402a1705421Sweingart 
403