1 /*
2 * ----------------------------------------------------------------------------
3 * "THE BEER-WARE LICENSE" (Revision 42):
4 * <phk@FreeBSD.org> wrote this file.  As long as you retain this notice you
5 * can do whatever you want with this stuff. If we meet some day, and you think
6 * this stuff is worth it, you can buy me a beer in return.   Poul-Henning Kamp
7 * ----------------------------------------------------------------------------
8 *
9 * $FreeBSD: stable/9/lib/libdisk/libdisk.h 178765 2008-05-04 22:24:40Z gonzo $
10 *
11 */
12 
13 #ifndef _LIBDISK_H_
14 #define _LIBDISK_H_
15 
16 /* #define DEBUG 1 */
17 /* You can define a particular architecture here if you are debugging. */
18 /* #define P_DEBUG p_sparc64 */
19 
20 #define MAX_NO_DISKS	32
21 /* Max # of disks Disk_Names() will return */
22 
23 #define MAX_SEC_SIZE    2048  /* maximum sector size that is supported */
24 #define MIN_SEC_SIZE	512   /* the sector size to end sensing at */
25 
26 enum platform {
27 	p_any,			/* for debugging ! */
28 	p_alpha,
29 	p_i386,
30 	p_pc98,
31 	p_sparc64,
32 	p_ia64,
33 	p_ppc,
34 	p_amd64,
35 	p_arm,
36 	p_mips
37 };
38 extern const enum platform platform;
39 
40 typedef enum {
41 	whole,
42 	unknown,
43 
44 	sun,
45 	pc98,
46 	mbr,
47 	gpt,
48 
49 	efi,
50 	fat,
51 	freebsd,
52 	extended,
53 	part,
54 	spare,
55 	unused,
56 
57 	apple
58 } chunk_e;
59 
60 __BEGIN_DECLS
61 #ifndef __ia64__
62 struct disk {
63 	char		*name;
64 	u_long		bios_cyl;
65 	u_long		bios_hd;
66 	u_long		bios_sect;
67 #ifdef PC98
68 	u_char		*bootipl;
69 	size_t		bootipl_size;
70 	u_char		*bootmenu;
71 	size_t		bootmenu_size;
72 #else
73 	u_char		*bootmgr;
74 	size_t		bootmgr_size;
75 #endif
76 	u_char		*boot1;
77 #if defined(__i386__) || defined(__amd64__) /* the i386 needs extra help... */
78 	u_char		*boot2;
79 #endif
80 	struct chunk	*chunks;
81 	u_long		sector_size; /* media sector size, a power of 2 */
82 };
83 #else	/* !__ia64__ */
84 struct disk {
85 	char		*name;
86 	struct chunk	*chunks;
87 	u_long		media_size;
88 	u_long		sector_size;
89 	u_long		lba_start;
90 	u_long		lba_end;
91 	u_int		gpt_size;	/* Number of entries */
92 };
93 #endif
94 
95 struct chunk {
96 	struct chunk	*next;
97 	struct chunk	*part;
98 	struct disk	*disk;
99 	daddr_t		offset;
100 	daddr_t		size;
101 	daddr_t		end;
102 	char		*sname;		/* PC98 field */
103 	char		*name;
104 	char		*oname;
105 	/* Used during Fixup_Names() to avoid renaming more than
106 	 * absolutely needed.
107 	 */
108 	chunk_e		type;
109 	int		subtype;
110 	u_long		flags;
111 	void		(*private_free)(void*);
112 	void		*(*private_clone)(void*);
113 	void		*private_data;
114 	/* For data private to the application, and the management
115 	 * thereof.  If the functions are not provided, no storage
116 	 * management is done, Cloning will just copy the pointer
117 	 * and freeing will just forget it.
118 	 */
119 };
120 
121 /*
122  * flags:
123  *
124  * ALIGN	-	This chunk should be aligned
125  * IS_ROOT	-	This 'part' is a rootfs, allocate 'a'
126  * ACTIVE	-	This is the active slice in the MBR
127  * FORCE_ALL	-	Force a dedicated disk for FreeBSD, bypassing
128  *			all BIOS geometry considerations
129  * AUTO_SIZE	-	This chunk was auto-sized and can fill-out a
130  *			following chunk if the following chunk is deleted.
131  * NEWFS	-	newfs pending, used to enable auto-resizing on
132  *			delete (along with AUTO_SIZE).
133  */
134 
135 #define CHUNK_ALIGN		0x0008
136 #define CHUNK_IS_ROOT		0x0010
137 #define CHUNK_ACTIVE		0x0020
138 #define CHUNK_FORCE_ALL		0x0040
139 #define CHUNK_AUTO_SIZE		0x0080
140 #define CHUNK_NEWFS		0x0100
141 #define	CHUNK_HAS_INDEX		0x0200
142 #define	CHUNK_ITOF(i)		((i & 0xFFFF) << 16)
143 #define	CHUNK_FTOI(f)		((f >> 16) & 0xFFFF)
144 
145 #define DELCHUNK_NORMAL		0x0000
146 #define DELCHUNK_RECOVER	0x0001
147 
148 const char *chunk_name(chunk_e);
149 
150 const char *
151 slice_type_name(int, int);
152 /* "chunk_n" for subtypes too */
153 
154 struct disk *
155 Open_Disk(const char *);
156 /* Will open the named disk, and return populated tree.  */
157 
158 void
159 Free_Disk(struct disk *);
160 /* Free a tree made with Open_Disk() or Clone_Disk() */
161 
162 void
163 Debug_Disk(struct disk *);
164 /* Print the content of the tree to stdout */
165 
166 void
167 Set_Bios_Geom(struct disk *, u_long, u_long, u_long);
168 /* Set the geometry the bios uses. */
169 
170 void
171 Sanitize_Bios_Geom(struct disk *);
172 /* Set the bios geometry to something sane */
173 
174 int
175 Insert_Chunk(struct chunk *, daddr_t, daddr_t, const char *, chunk_e, int,
176 	u_long, const char *);
177 
178 int
179 Delete_Chunk2(struct disk *, struct chunk *, int);
180 /* Free a chunk of disk_space modified by the passed flags. */
181 
182 int
183 Delete_Chunk(struct disk *, struct chunk *);
184 /* Free a chunk of disk_space */
185 
186 void
187 Collapse_Disk(struct disk *);
188 /* Experimental, do not use. */
189 
190 int
191 Collapse_Chunk(struct disk *, struct chunk *);
192 /* Experimental, do not use. */
193 
194 int
195 Create_Chunk(struct disk *, daddr_t, daddr_t, chunk_e, int, u_long, const char *);
196 /* Create a chunk with the specified paramters */
197 
198 void
199 All_FreeBSD(struct disk *, int);
200 /*
201  * Make one FreeBSD chunk covering the entire disk;
202  * if force_all is set, bypass all BIOS geometry
203  * considerations.
204  */
205 
206 char *
207 CheckRules(const struct disk *);
208 /* Return char* to warnings about broken design rules in this disklayout */
209 
210 char **
211 Disk_Names(void);
212 /*
213  * Return char** with all disk's names (wd0, wd1 ...).  You must free
214  * each pointer, as well as the array by hand
215  */
216 
217 #ifdef PC98
218 void
219 Set_Boot_Mgr(struct disk *, const u_char *, const size_t, const u_char *,
220 	const size_t);
221 #else
222 void
223 Set_Boot_Mgr(struct disk *, const u_char *, const size_t);
224 #endif
225 /*
226  * Use this boot-manager on this disk.  Gets written when Write_Disk()
227  * is called
228  */
229 
230 int
231 Set_Boot_Blocks(struct disk *, const u_char *, const u_char *);
232 /*
233  * Use these boot-blocks on this disk.  Gets written when Write_Disk()
234  * is called. Returns nonzero upon failure.
235  */
236 
237 int
238 Write_Disk(const struct disk *);
239 /* Write all the MBRs, disklabels, bootblocks and boot managers */
240 
241 daddr_t
242 Next_Cyl_Aligned(const struct disk *, daddr_t);
243 /* Round offset up to next cylinder according to the bios-geometry */
244 
245 daddr_t
246 Prev_Cyl_Aligned(const struct disk *, daddr_t);
247 /* Round offset down to previous cylinder according to the bios-geometry */
248 
249 int
250 Track_Aligned(const struct disk *, daddr_t);
251 /* Check if offset is aligned on a track according to the bios geometry */
252 
253 daddr_t
254 Next_Track_Aligned(const struct disk *, daddr_t);
255 /* Round offset up to next track according to the bios-geometry */
256 
257 daddr_t
258 Prev_Track_Aligned(const struct disk *, daddr_t);
259 /* Check if offset is aligned on a track according to the bios geometry */
260 
261 struct chunk *
262 Create_Chunk_DWIM(struct disk *, struct chunk *, daddr_t, chunk_e, int,
263 	u_long);
264 /*
265  * This one creates a partition inside the given parent of the given
266  * size, and returns a pointer to it.  The first unused chunk big
267  * enough is used.
268  */
269 
270 char *
271 ShowChunkFlags(struct chunk *);
272 /* Return string to show flags. */
273 
274 /*
275  * Implementation details  >>> DO NOT USE <<<
276  */
277 
278 struct disklabel;
279 
280 void Fill_Disklabel(struct disklabel *, const struct disk *,
281 	const struct chunk *);
282 void Debug_Chunk(struct chunk *);
283 struct chunk *New_Chunk(void);
284 void Free_Chunk(struct chunk *);
285 struct chunk *Clone_Chunk(const struct chunk *);
286 int Add_Chunk(struct disk *, daddr_t, daddr_t, const char *, chunk_e, int,
287 	u_long, const char *);
288 void *read_block(int, daddr_t, u_long);
289 int write_block(int, daddr_t, const void *, u_long);
290 struct disklabel *read_disklabel(int, daddr_t, u_long);
291 struct disk *Int_Open_Disk(const char *, char *);
292 int Fixup_Names(struct disk *);
293 int MakeDevChunk(const struct chunk *, const char *);
294 __END_DECLS
295 
296 #define dprintf	printf
297 
298 /* TODO
299  *
300  * Need an error string mechanism from the functions instead of warn()
301  *
302  * Make sure only FreeBSD start at offset==0
303  *
304  * Collapse must align.
305  *
306  * Make Write_Disk(struct disk*)
307  *
308  * Consider booting from OnTrack'ed disks.
309  *
310  * Get Bios-geom, ST506 & OnTrack from driver (or otherwise)
311  *
312  * Make Create_DWIM().
313  *
314  * Make Is_Unchanged(struct disk *d1, struct chunk *c1)
315  *
316  * don't rename slices unless we have to
317  *
318  *Sample output from tst01:
319  *
320  * Debug_Disk(wd0)  flags=0  bios_geom=0/0/0
321  * >>        0x3d040          0    1411200    1411199 wd0      0 whole    0 0
322  * >>>>      0x3d080          0     960120     960119 wd0s1    3 freebsd  0 8
323  * >>>>>>    0x3d100          0      40960      40959 wd0s1a   5 part     0 0
324  * >>>>>>    0x3d180      40960     131072     172031 wd0s1b   5 part     0 0
325  * >>>>>>    0x3d1c0     172032     409600     581631 wd0s1e   5 part     0 0
326  * >>>>>>    0x3d200     581632     378488     960119 wd0s1f   5 part     0 0
327  * >>>>      0x3d140     960120       5670     965789 wd0s2    4 extended 0 8
328  * >>>>>>    0x3d2c0     960120         63     960182 -        6 unused   0 0
329  * >>>>>>    0x3d0c0     960183       5607     965789 wd0s5    2 fat      0 8
330  * >>>>      0x3d280     965790       1890     967679 wd0s3    1 foo      -2 8
331  * >>>>      0x3d300     967680     443520    1411199 wd0s4    3 freebsd  0 8
332  * >>>>>>    0x3d340     967680     443520    1411199 wd0s4a   5 part     0 0
333  *
334  * ^            ^           ^          ^          ^     ^      ^ ^        ^ ^
335  * level    chunkptr      start      size        end  name    type  subtype flags
336  *
337  * Underlying data structure:
338  *
339  *	Legend:
340  *		<struct chunk> --> part
341  *			|
342  *			v next
343  *
344  *	<wd0> --> <wd0s1> --> <wd0s1a>
345  *		     |           |
346  *		     |           v
347  *		     |        <wd0s1b>
348  *		     |           |
349  *		     |           v
350  *		     |        <wd0s1e>
351  *		     |           |
352  *		     |           v
353  *		     |        <wd0s1f>
354  *		     |
355  *		     v
356  *		  <wd0s2> --> <unused>
357  *		     |           |
358  *		     |           v
359  *		     |        <wd0s5>
360  *		     |
361  *		     v
362  *		  <wd0s3>
363  *		     |
364  *		     v
365  *		  <wd0s4> --> <wd0s4a>
366  *
367  *
368  */
369 
370 #endif /* _LIBDISK_H_ */
371