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