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 #if defined(CONFIG_SAM440EP) || defined(CONFIG_SAM440EP_FLEX)
51 extern block_dev_desc_t * p_sii_get_dev(const unsigned unit);
52 extern block_dev_desc_t * s_sii_get_dev(const unsigned unit);
53 extern block_dev_desc_t * s_4_sii_get_dev(const unsigned unit);
54 #elif defined(CONFIG_SAM460EX)
55 extern block_dev_desc_t * s_sii_get_dev(const unsigned unit);
56 extern block_dev_desc_t * s_4_sii_get_dev(const unsigned unit);
57 extern block_dev_desc_t * sata2_460_get_dev(const unsigned unit);
58 #endif
59 
60 static const struct block_drvr block_drvr[] = {
61 #if defined(CONFIG_CMD_IDE)
62 	{ .name = "ide", .get_dev = ide_get_dev, },
63 #endif
64 #if defined(CONFIG_CMD_SATA)
65 	{.name = "sata", .get_dev = sata_get_dev, },
66 #endif
67 #if defined(CONFIG_CMD_SCSI)
68 	{ .name = "scsi", .get_dev = scsi_get_dev, },
69 #endif
70 #if defined(CONFIG_CMD_USB) && defined(CONFIG_USB_STORAGE)
71 	{ .name = "usb", .get_dev = usb_stor_get_dev, },
72 #endif
73 #if defined(CONFIG_MMC)
74 	{ .name = "mmc", .get_dev = mmc_get_dev, },
75 #endif
76 #if defined(CONFIG_SYSTEMACE)
77 	{ .name = "ace", .get_dev = systemace_get_dev, },
78 #endif
79 #if defined(CONFIG_CMD_MG_DISK)
80 	{ .name = "mgd", .get_dev = mg_disk_get_dev, },
81 #endif
82 #if defined(CONFIG_SAM440EP) || defined(CONFIG_SAM440EP_FLEX)
83 	{ .name = "psii", .get_dev = p_sii_get_dev, },
84 	{ .name = "ssii", .get_dev = s_sii_get_dev, },
85 	{ .name = "s4sii", .get_dev = s_4_sii_get_dev, },
86 #elif defined(CONFIG_SAM460EX)
87 	{ .name = "ssii", .get_dev = s_sii_get_dev, },
88 	{ .name = "s4sii", .get_dev = s_4_sii_get_dev, },
89 	{ .name = "sata2-460", .get_dev = sata2_460_get_dev, },
90 #endif
91 	{ },
92 };
93 
94 DECLARE_GLOBAL_DATA_PTR;
95 
get_dev(char * ifname,int dev)96 block_dev_desc_t *get_dev(char* ifname, int dev)
97 {
98 	const struct block_drvr *drvr = block_drvr;
99 	block_dev_desc_t* (*reloc_get_dev)(int dev);
100 
101 	while (drvr->name) {
102 		reloc_get_dev = drvr->get_dev;
103 #ifndef CONFIG_RELOC_FIXUP_WORKS
104 		reloc_get_dev += gd->reloc_off;
105 #endif
106 		if (strncmp(ifname, drvr->name, strlen(drvr->name)) == 0)
107 			return reloc_get_dev(dev);
108 		drvr++;
109 	}
110 	return NULL;
111 }
112 #else
get_dev(char * ifname,int dev)113 block_dev_desc_t *get_dev(char* ifname, int dev)
114 {
115 	return NULL;
116 }
117 #endif
118 
119 #if (defined(CONFIG_CMD_IDE) || \
120      defined(CONFIG_CMD_MG_DISK) || \
121      defined(CONFIG_CMD_SATA) || \
122      defined(CONFIG_CMD_SCSI) || \
123      defined(CONFIG_CMD_USB) || \
124      defined(CONFIG_MMC) || \
125      defined(CONFIG_SYSTEMACE) )
126 
127 /* ------------------------------------------------------------------------- */
128 /*
129  * reports device info to the user
130  */
dev_print(block_dev_desc_t * dev_desc)131 void dev_print (block_dev_desc_t *dev_desc)
132 {
133 #ifdef CONFIG_LBA48
134 	uint64_t lba512; /* number of blocks if 512bytes block size */
135 #else
136 	lbaint_t lba512;
137 #endif
138 
139 	if (dev_desc->type == DEV_TYPE_UNKNOWN) {
140 		puts ("not available\n");
141 		return;
142 	}
143 
144 	switch (dev_desc->if_type) {
145 	case IF_TYPE_SCSI:
146 		printf ("(%d:%d) Vendor: %s Prod.: %s Rev: %s\n",
147 			dev_desc->target,dev_desc->lun,
148 			dev_desc->vendor,
149 			dev_desc->product,
150 			dev_desc->revision);
151 		break;
152 	case IF_TYPE_ATAPI:
153 	case IF_TYPE_IDE:
154 	case IF_TYPE_SATA:
155 		printf ("Model: %s Firm: %s Ser#: %s\n",
156 			dev_desc->vendor,
157 			dev_desc->revision,
158 			dev_desc->product);
159 		break;
160 	case IF_TYPE_SD:
161 	case IF_TYPE_MMC:
162 	case IF_TYPE_USB:
163 		printf ("Vendor: %s Rev: %s Prod: %s\n",
164 			dev_desc->vendor,
165 			dev_desc->revision,
166 			dev_desc->product);
167 		break;
168 	case IF_TYPE_DOC:
169 		puts("device type DOC\n");
170 		return;
171 	case IF_TYPE_UNKNOWN:
172 		puts("device type unknown\n");
173 		return;
174 	default:
175 		printf("Unhandled device type: %i\n", dev_desc->if_type);
176 		return;
177 	}
178 	puts ("            Type: ");
179 	if (dev_desc->removable)
180 		puts ("Removable ");
181 	switch (dev_desc->type & 0x1F) {
182 	case DEV_TYPE_HARDDISK:
183 		puts ("Hard Disk");
184 		break;
185 	case DEV_TYPE_CDROM:
186 		puts ("CD ROM");
187 		break;
188 	case DEV_TYPE_OPDISK:
189 		puts ("Optical Device");
190 		break;
191 	case DEV_TYPE_TAPE:
192 		puts ("Tape");
193 		break;
194 	default:
195 		printf ("# %02X #", dev_desc->type & 0x1F);
196 		break;
197 	}
198 	puts ("\n");
199 	if ((dev_desc->lba * dev_desc->blksz)>0L) {
200 		ulong mb, mb_quot, mb_rem, gb, gb_quot, gb_rem;
201 		lbaint_t lba;
202 
203 		lba = dev_desc->lba;
204 
205 		lba512 = (lba * (dev_desc->blksz/512));
206 		mb = (10 * lba512) / 2048;	/* 2048 = (1024 * 1024) / 512 MB */
207 		/* round to 1 digit */
208 		mb_quot	= mb / 10;
209 		mb_rem	= mb - (10 * mb_quot);
210 
211 		gb = mb / 1024;
212 		gb_quot	= gb / 10;
213 		gb_rem	= gb - (10 * gb_quot);
214 #ifdef CONFIG_LBA48
215 		if (dev_desc->lba48)
216 			printf ("            Supports 48-bit addressing\n");
217 #endif
218 #if defined(CONFIG_SYS_64BIT_LBA)
219 		printf ("            Capacity: %ld.%ld MB = %ld.%ld GB (%Ld x %ld)\n",
220 			mb_quot, mb_rem,
221 			gb_quot, gb_rem,
222 			lba,
223 			dev_desc->blksz);
224 #else
225 		printf ("            Capacity: %ld.%ld MB = %ld.%ld GB (%ld x %ld)\n",
226 			mb_quot, mb_rem,
227 			gb_quot, gb_rem,
228 			(ulong)lba,
229 			dev_desc->blksz);
230 #endif
231 	} else {
232 		puts ("            Capacity: not available\n");
233 	}
234 }
235 #endif
236 
237 #if (defined(CONFIG_CMD_IDE) || \
238      defined(CONFIG_CMD_MG_DISK) || \
239      defined(CONFIG_CMD_SATA) || \
240      defined(CONFIG_CMD_SCSI) || \
241      defined(CONFIG_CMD_USB) || \
242      defined(CONFIG_MMC)		|| \
243      defined(CONFIG_SYSTEMACE) )
244 
245 #if defined(CONFIG_MAC_PARTITION) || \
246     defined(CONFIG_DOS_PARTITION) || \
247     defined(CONFIG_ISO_PARTITION) || \
248     defined(CONFIG_AMIGA_PARTITION) || \
249     defined(CONFIG_EFI_PARTITION)
250 
init_part(block_dev_desc_t * dev_desc)251 void init_part (block_dev_desc_t * dev_desc)
252 {
253 #ifdef CONFIG_ISO_PARTITION
254 	if (test_part_iso(dev_desc) == 0) {
255 		dev_desc->part_type = PART_TYPE_ISO;
256 		return;
257 	}
258 #endif
259 
260 #ifdef CONFIG_MAC_PARTITION
261 	if (test_part_mac(dev_desc) == 0) {
262 		dev_desc->part_type = PART_TYPE_MAC;
263 		return;
264 	}
265 #endif
266 
267 /* must be placed before DOS partition detection */
268 #ifdef CONFIG_EFI_PARTITION
269 	if (test_part_efi(dev_desc) == 0) {
270 		dev_desc->part_type = PART_TYPE_EFI;
271 		return;
272 	}
273 #endif
274 
275 #ifdef CONFIG_DOS_PARTITION
276 	if (test_part_dos(dev_desc) == 0) {
277 		dev_desc->part_type = PART_TYPE_DOS;
278 		return;
279 	}
280 #endif
281 
282 #ifdef CONFIG_AMIGA_PARTITION
283 	if (test_part_amiga(dev_desc) == 0) {
284 	    dev_desc->part_type = PART_TYPE_AMIGA;
285 	    return;
286 	}
287 #endif
288 }
289 
290 
get_partition_info(block_dev_desc_t * dev_desc,int part,disk_partition_t * info)291 int get_partition_info (block_dev_desc_t *dev_desc, int part
292 					, disk_partition_t *info)
293 {
294 	switch (dev_desc->part_type) {
295 #ifdef CONFIG_MAC_PARTITION
296 	case PART_TYPE_MAC:
297 		if (get_partition_info_mac(dev_desc,part,info) == 0) {
298 			PRINTF ("## Valid MAC partition found ##\n");
299 			return (0);
300 		}
301 		break;
302 #endif
303 
304 #ifdef CONFIG_DOS_PARTITION
305 	case PART_TYPE_DOS:
306 		if (get_partition_info_dos(dev_desc,part,info) == 0) {
307 			PRINTF ("## Valid DOS partition found ##\n");
308 			return (0);
309 		}
310 		break;
311 #endif
312 
313 #ifdef CONFIG_ISO_PARTITION
314 	case PART_TYPE_ISO:
315 		if (get_partition_info_iso(dev_desc,part,info) == 0) {
316 			PRINTF ("## Valid ISO boot partition found ##\n");
317 			return (0);
318 		}
319 		break;
320 #endif
321 
322 #ifdef CONFIG_AMIGA_PARTITION
323 	case PART_TYPE_AMIGA:
324 	    if (get_partition_info_amiga(dev_desc, part, info) == 0)
325 	    {
326 		PRINTF ("## Valid Amiga partition found ##\n");
327 		return (0);
328 	    }
329 	    break;
330 #endif
331 
332 #ifdef CONFIG_EFI_PARTITION
333 	case PART_TYPE_EFI:
334 		if (get_partition_info_efi(dev_desc,part,info) == 0) {
335 			PRINTF ("## Valid EFI partition found ##\n");
336 			return (0);
337 		}
338 		break;
339 #endif
340 	default:
341 		break;
342 	}
343 	return (-1);
344 }
345 
print_part_header(const char * type,block_dev_desc_t * dev_desc)346 static void print_part_header (const char *type, block_dev_desc_t * dev_desc)
347 {
348 	puts ("\nPartition Map for ");
349 	switch (dev_desc->if_type) {
350 	case IF_TYPE_IDE:
351 		puts ("IDE");
352 		break;
353 	case IF_TYPE_SATA:
354 		puts ("SATA");
355 		break;
356 	case IF_TYPE_SCSI:
357 		puts ("SCSI");
358 		break;
359 	case IF_TYPE_ATAPI:
360 		puts ("ATAPI");
361 		break;
362 	case IF_TYPE_USB:
363 		puts ("USB");
364 		break;
365 	case IF_TYPE_DOC:
366 		puts ("DOC");
367 		break;
368 	default:
369 		puts ("UNKNOWN");
370 		break;
371 	}
372 	printf (" device %d  --   Partition Type: %s\n\n",
373 			dev_desc->dev, type);
374 }
375 
print_part(block_dev_desc_t * dev_desc)376 void print_part (block_dev_desc_t * dev_desc)
377 {
378 
379 		switch (dev_desc->part_type) {
380 #ifdef CONFIG_MAC_PARTITION
381 	case PART_TYPE_MAC:
382 		PRINTF ("## Testing for valid MAC partition ##\n");
383 		print_part_header ("MAC", dev_desc);
384 		print_part_mac (dev_desc);
385 		return;
386 #endif
387 #ifdef CONFIG_DOS_PARTITION
388 	case PART_TYPE_DOS:
389 		PRINTF ("## Testing for valid DOS partition ##\n");
390 		print_part_header ("DOS", dev_desc);
391 		print_part_dos (dev_desc);
392 		return;
393 #endif
394 
395 #ifdef CONFIG_ISO_PARTITION
396 	case PART_TYPE_ISO:
397 		PRINTF ("## Testing for valid ISO Boot partition ##\n");
398 		print_part_header ("ISO", dev_desc);
399 		print_part_iso (dev_desc);
400 		return;
401 #endif
402 
403 #ifdef CONFIG_AMIGA_PARTITION
404 	case PART_TYPE_AMIGA:
405 	    PRINTF ("## Testing for a valid Amiga partition ##\n");
406 	    print_part_header ("AMIGA", dev_desc);
407 	    print_part_amiga (dev_desc);
408 	    return;
409 #endif
410 
411 #ifdef CONFIG_EFI_PARTITION
412 	case PART_TYPE_EFI:
413 		PRINTF ("## Testing for valid EFI partition ##\n");
414 		print_part_header ("EFI", dev_desc);
415 		print_part_efi (dev_desc);
416 		return;
417 #endif
418 	}
419 	puts ("## Unknown partition table\n");
420 }
421 
422 
423 #else	/* neither MAC nor DOS nor ISO nor AMIGA nor EFI partition configured */
424 # error neither CONFIG_MAC_PARTITION nor CONFIG_DOS_PARTITION
425 # error nor CONFIG_ISO_PARTITION nor CONFIG_AMIGA_PARTITION
426 # error nor CONFIG_EFI_PARTITION configured!
427 #endif
428 
429 #endif
430