xref: /openbmc/u-boot/disk/part.c (revision 84bf7ca5)
1 /*
2  * (C) Copyright 2001
3  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
4  *
5  * See file CREDITS for list of people who contributed to this
6  * project.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License as
10  * published by the Free Software Foundation; either version 2 of
11  * the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21  * MA 02111-1307 USA
22  */
23 
24 #include <common.h>
25 #include <command.h>
26 #include <ide.h>
27 #include <part.h>
28 
29 #undef	PART_DEBUG
30 
31 #ifdef	PART_DEBUG
32 #define	PRINTF(fmt,args...)	printf (fmt ,##args)
33 #else
34 #define PRINTF(fmt,args...)
35 #endif
36 
37 #if (defined(CONFIG_CMD_IDE) || \
38      defined(CONFIG_CMD_MG_DISK) || \
39      defined(CONFIG_CMD_SATA) || \
40      defined(CONFIG_CMD_SCSI) || \
41      defined(CONFIG_CMD_USB) || \
42      defined(CONFIG_MMC) || \
43      defined(CONFIG_SYSTEMACE) )
44 
45 struct block_drvr {
46 	char *name;
47 	block_dev_desc_t* (*get_dev)(int dev);
48 };
49 
50 static const struct block_drvr block_drvr[] = {
51 #if defined(CONFIG_CMD_IDE)
52 	{ .name = "ide", .get_dev = ide_get_dev, },
53 #endif
54 #if defined(CONFIG_CMD_SATA)
55 	{.name = "sata", .get_dev = sata_get_dev, },
56 #endif
57 #if defined(CONFIG_CMD_SCSI)
58 	{ .name = "scsi", .get_dev = scsi_get_dev, },
59 #endif
60 #if defined(CONFIG_CMD_USB) && defined(CONFIG_USB_STORAGE)
61 	{ .name = "usb", .get_dev = usb_stor_get_dev, },
62 #endif
63 #if defined(CONFIG_MMC)
64 	{ .name = "mmc", .get_dev = mmc_get_dev, },
65 #endif
66 #if defined(CONFIG_SYSTEMACE)
67 	{ .name = "ace", .get_dev = systemace_get_dev, },
68 #endif
69 #if defined(CONFIG_CMD_MG_DISK)
70 	{ .name = "mgd", .get_dev = mg_disk_get_dev, },
71 #endif
72 	{ },
73 };
74 
75 DECLARE_GLOBAL_DATA_PTR;
76 
77 block_dev_desc_t *get_dev(char* ifname, int dev)
78 {
79 	const struct block_drvr *drvr = block_drvr;
80 	block_dev_desc_t* (*reloc_get_dev)(int dev);
81 
82 	while (drvr->name) {
83 		reloc_get_dev = drvr->get_dev + gd->reloc_off;
84 		if (strncmp(ifname, drvr->name, strlen(drvr->name)) == 0)
85 			return reloc_get_dev(dev);
86 		drvr++;
87 	}
88 	return NULL;
89 }
90 #else
91 block_dev_desc_t *get_dev(char* ifname, int dev)
92 {
93 	return NULL;
94 }
95 #endif
96 
97 #if (defined(CONFIG_CMD_IDE) || \
98      defined(CONFIG_CMD_MG_DISK) || \
99      defined(CONFIG_CMD_SATA) || \
100      defined(CONFIG_CMD_SCSI) || \
101      defined(CONFIG_CMD_USB) || \
102      defined(CONFIG_MMC) || \
103      defined(CONFIG_SYSTEMACE) )
104 
105 /* ------------------------------------------------------------------------- */
106 /*
107  * reports device info to the user
108  */
109 void dev_print (block_dev_desc_t *dev_desc)
110 {
111 #ifdef CONFIG_LBA48
112 	uint64_t lba512; /* number of blocks if 512bytes block size */
113 #else
114 	lbaint_t lba512;
115 #endif
116 
117 	switch (dev_desc->if_type) {
118 	case IF_TYPE_SCSI:
119 		printf ("(%d:%d) Vendor: %s Prod.: %s Rev: %s\n",
120 			dev_desc->target,dev_desc->lun,
121 			dev_desc->vendor,
122 			dev_desc->product,
123 			dev_desc->revision);
124 		break;
125 	case IF_TYPE_ATAPI:
126 	case IF_TYPE_IDE:
127 	case IF_TYPE_SATA:
128 		printf ("Model: %s Firm: %s Ser#: %s\n",
129 			dev_desc->vendor,
130 			dev_desc->revision,
131 			dev_desc->product);
132 		break;
133 	case IF_TYPE_SD:
134 	case IF_TYPE_MMC:
135 	case IF_TYPE_USB:
136 		printf ("Vendor: %s Rev: %s Prod: %s\n",
137 			dev_desc->vendor,
138 			dev_desc->revision,
139 			dev_desc->product);
140 		break;
141 	case IF_TYPE_DOC:
142 		puts("device type DOC\n");
143 		return;
144 	case IF_TYPE_UNKNOWN:
145 		puts("device type unknown\n");
146 		return;
147 	default:
148 		printf("Unhandled device type: %i\n", dev_desc->if_type);
149 		return;
150 	}
151 	puts ("            Type: ");
152 	if (dev_desc->removable)
153 		puts ("Removable ");
154 	switch (dev_desc->type & 0x1F) {
155 	case DEV_TYPE_HARDDISK:
156 		puts ("Hard Disk");
157 		break;
158 	case DEV_TYPE_CDROM:
159 		puts ("CD ROM");
160 		break;
161 	case DEV_TYPE_OPDISK:
162 		puts ("Optical Device");
163 		break;
164 	case DEV_TYPE_TAPE:
165 		puts ("Tape");
166 		break;
167 	default:
168 		printf ("# %02X #", dev_desc->type & 0x1F);
169 		break;
170 	}
171 	puts ("\n");
172 	if ((dev_desc->lba * dev_desc->blksz)>0L) {
173 		ulong mb, mb_quot, mb_rem, gb, gb_quot, gb_rem;
174 		lbaint_t lba;
175 
176 		lba = dev_desc->lba;
177 
178 		lba512 = (lba * (dev_desc->blksz/512));
179 		mb = (10 * lba512) / 2048;	/* 2048 = (1024 * 1024) / 512 MB */
180 		/* round to 1 digit */
181 		mb_quot	= mb / 10;
182 		mb_rem	= mb - (10 * mb_quot);
183 
184 		gb = mb / 1024;
185 		gb_quot	= gb / 10;
186 		gb_rem	= gb - (10 * gb_quot);
187 #ifdef CONFIG_LBA48
188 		if (dev_desc->lba48)
189 			printf ("            Supports 48-bit addressing\n");
190 #endif
191 #if defined(CONFIG_SYS_64BIT_LBA) && defined(CONFIG_SYS_64BIT_VSPRINTF)
192 		printf ("            Capacity: %ld.%ld MB = %ld.%ld GB (%Ld x %ld)\n",
193 			mb_quot, mb_rem,
194 			gb_quot, gb_rem,
195 			lba,
196 			dev_desc->blksz);
197 #else
198 		printf ("            Capacity: %ld.%ld MB = %ld.%ld GB (%ld x %ld)\n",
199 			mb_quot, mb_rem,
200 			gb_quot, gb_rem,
201 			(ulong)lba,
202 			dev_desc->blksz);
203 #endif
204 	} else {
205 		puts ("            Capacity: not available\n");
206 	}
207 }
208 #endif
209 
210 #if (defined(CONFIG_CMD_IDE) || \
211      defined(CONFIG_CMD_MG_DISK) || \
212      defined(CONFIG_CMD_SATA) || \
213      defined(CONFIG_CMD_SCSI) || \
214      defined(CONFIG_CMD_USB) || \
215      defined(CONFIG_MMC)		|| \
216      defined(CONFIG_SYSTEMACE) )
217 
218 #if defined(CONFIG_MAC_PARTITION) || \
219     defined(CONFIG_DOS_PARTITION) || \
220     defined(CONFIG_ISO_PARTITION) || \
221     defined(CONFIG_AMIGA_PARTITION) || \
222     defined(CONFIG_EFI_PARTITION)
223 
224 void init_part (block_dev_desc_t * dev_desc)
225 {
226 #ifdef CONFIG_ISO_PARTITION
227 	if (test_part_iso(dev_desc) == 0) {
228 		dev_desc->part_type = PART_TYPE_ISO;
229 		return;
230 	}
231 #endif
232 
233 #ifdef CONFIG_MAC_PARTITION
234 	if (test_part_mac(dev_desc) == 0) {
235 		dev_desc->part_type = PART_TYPE_MAC;
236 		return;
237 	}
238 #endif
239 
240 /* must be placed before DOS partition detection */
241 #ifdef CONFIG_EFI_PARTITION
242 	if (test_part_efi(dev_desc) == 0) {
243 		dev_desc->part_type = PART_TYPE_EFI;
244 		return;
245 	}
246 #endif
247 
248 #ifdef CONFIG_DOS_PARTITION
249 	if (test_part_dos(dev_desc) == 0) {
250 		dev_desc->part_type = PART_TYPE_DOS;
251 		return;
252 	}
253 #endif
254 
255 #ifdef CONFIG_AMIGA_PARTITION
256 	if (test_part_amiga(dev_desc) == 0) {
257 	    dev_desc->part_type = PART_TYPE_AMIGA;
258 	    return;
259 	}
260 #endif
261 }
262 
263 
264 int get_partition_info (block_dev_desc_t *dev_desc, int part
265 					, disk_partition_t *info)
266 {
267 	switch (dev_desc->part_type) {
268 #ifdef CONFIG_MAC_PARTITION
269 	case PART_TYPE_MAC:
270 		if (get_partition_info_mac(dev_desc,part,info) == 0) {
271 			PRINTF ("## Valid MAC partition found ##\n");
272 			return (0);
273 		}
274 		break;
275 #endif
276 
277 #ifdef CONFIG_DOS_PARTITION
278 	case PART_TYPE_DOS:
279 		if (get_partition_info_dos(dev_desc,part,info) == 0) {
280 			PRINTF ("## Valid DOS partition found ##\n");
281 			return (0);
282 		}
283 		break;
284 #endif
285 
286 #ifdef CONFIG_ISO_PARTITION
287 	case PART_TYPE_ISO:
288 		if (get_partition_info_iso(dev_desc,part,info) == 0) {
289 			PRINTF ("## Valid ISO boot partition found ##\n");
290 			return (0);
291 		}
292 		break;
293 #endif
294 
295 #ifdef CONFIG_AMIGA_PARTITION
296 	case PART_TYPE_AMIGA:
297 	    if (get_partition_info_amiga(dev_desc, part, info) == 0)
298 	    {
299 		PRINTF ("## Valid Amiga partition found ##\n");
300 		return (0);
301 	    }
302 	    break;
303 #endif
304 
305 #ifdef CONFIG_EFI_PARTITION
306 	case PART_TYPE_EFI:
307 		if (get_partition_info_efi(dev_desc,part,info) == 0) {
308 			PRINTF ("## Valid EFI partition found ##\n");
309 			return (0);
310 		}
311 		break;
312 #endif
313 	default:
314 		break;
315 	}
316 	return (-1);
317 }
318 
319 static void print_part_header (const char *type, block_dev_desc_t * dev_desc)
320 {
321 	puts ("\nPartition Map for ");
322 	switch (dev_desc->if_type) {
323 	case IF_TYPE_IDE:
324 		puts ("IDE");
325 		break;
326 	case IF_TYPE_SATA:
327 		puts ("SATA");
328 		break;
329 	case IF_TYPE_SCSI:
330 		puts ("SCSI");
331 		break;
332 	case IF_TYPE_ATAPI:
333 		puts ("ATAPI");
334 		break;
335 	case IF_TYPE_USB:
336 		puts ("USB");
337 		break;
338 	case IF_TYPE_DOC:
339 		puts ("DOC");
340 		break;
341 	default:
342 		puts ("UNKNOWN");
343 		break;
344 	}
345 	printf (" device %d  --   Partition Type: %s\n\n",
346 			dev_desc->dev, type);
347 }
348 
349 void print_part (block_dev_desc_t * dev_desc)
350 {
351 
352 		switch (dev_desc->part_type) {
353 #ifdef CONFIG_MAC_PARTITION
354 	case PART_TYPE_MAC:
355 		PRINTF ("## Testing for valid MAC partition ##\n");
356 		print_part_header ("MAC", dev_desc);
357 		print_part_mac (dev_desc);
358 		return;
359 #endif
360 #ifdef CONFIG_DOS_PARTITION
361 	case PART_TYPE_DOS:
362 		PRINTF ("## Testing for valid DOS partition ##\n");
363 		print_part_header ("DOS", dev_desc);
364 		print_part_dos (dev_desc);
365 		return;
366 #endif
367 
368 #ifdef CONFIG_ISO_PARTITION
369 	case PART_TYPE_ISO:
370 		PRINTF ("## Testing for valid ISO Boot partition ##\n");
371 		print_part_header ("ISO", dev_desc);
372 		print_part_iso (dev_desc);
373 		return;
374 #endif
375 
376 #ifdef CONFIG_AMIGA_PARTITION
377 	case PART_TYPE_AMIGA:
378 	    PRINTF ("## Testing for a valid Amiga partition ##\n");
379 	    print_part_header ("AMIGA", dev_desc);
380 	    print_part_amiga (dev_desc);
381 	    return;
382 #endif
383 
384 #ifdef CONFIG_EFI_PARTITION
385 	case PART_TYPE_EFI:
386 		PRINTF ("## Testing for valid EFI partition ##\n");
387 		print_part_header ("EFI", dev_desc);
388 		print_part_efi (dev_desc);
389 		return;
390 #endif
391 	}
392 	puts ("## Unknown partition table\n");
393 }
394 
395 
396 #else	/* neither MAC nor DOS nor ISO nor AMIGA nor EFI partition configured */
397 # error neither CONFIG_MAC_PARTITION nor CONFIG_DOS_PARTITION
398 # error nor CONFIG_ISO_PARTITION nor CONFIG_AMIGA_PARTITION
399 # error nor CONFIG_EFI_PARTITION configured!
400 #endif
401 
402 #endif
403