tizen 2.4 release
[profile/mobile/platform/kernel/u-boot-tm1.git] / disk / part.c
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 #include "part_uefi.h"
30
31 #undef  PART_DEBUG
32
33 #ifdef  PART_DEBUG
34 #define PRINTF(fmt,args...)     printf (fmt ,##args)
35 #else
36 #define PRINTF(fmt,args...)
37 #endif
38
39 #if (defined(CONFIG_CMD_IDE) || \
40      defined(CONFIG_CMD_MG_DISK) || \
41      defined(CONFIG_CMD_SATA) || \
42      defined(CONFIG_CMD_SCSI) || \
43      defined(CONFIG_CMD_USB) || \
44      defined(CONFIG_MMC) || \
45      defined(CONFIG_SYSTEMACE) )
46
47 struct block_drvr {
48         char *name;
49         block_dev_desc_t* (*get_dev)(int dev);
50 };
51
52 static const struct block_drvr block_drvr[] = {
53 #if defined(CONFIG_CMD_IDE)
54         { .name = "ide", .get_dev = ide_get_dev, },
55 #endif
56 #if defined(CONFIG_CMD_SATA)
57         {.name = "sata", .get_dev = sata_get_dev, },
58 #endif
59 #if defined(CONFIG_CMD_SCSI)
60         { .name = "scsi", .get_dev = scsi_get_dev, },
61 #endif
62 #if defined(CONFIG_CMD_USB) && defined(CONFIG_USB_STORAGE)
63         { .name = "usb", .get_dev = usb_stor_get_dev, },
64 #endif
65 #if defined(CONFIG_MMC)
66         { .name = "mmc", .get_dev = mmc_get_dev, },
67 #endif
68 #if defined(CONFIG_SYSTEMACE)
69         { .name = "ace", .get_dev = systemace_get_dev, },
70 #endif
71 #if defined(CONFIG_CMD_MG_DISK)
72         { .name = "mgd", .get_dev = mg_disk_get_dev, },
73 #endif
74         { },
75 };
76
77 DECLARE_GLOBAL_DATA_PTR;
78
79 block_dev_desc_t *get_dev(char* ifname, int dev)
80 {
81         const struct block_drvr *drvr = block_drvr;
82         block_dev_desc_t* (*reloc_get_dev)(int dev);
83         char *name;
84
85         name = drvr->name;
86 #ifdef CONFIG_NEEDS_MANUAL_RELOC
87         name += gd->reloc_off;
88 #endif
89         while (name) {
90                 name = drvr->name;
91                 reloc_get_dev = drvr->get_dev;
92 #ifdef CONFIG_NEEDS_MANUAL_RELOC
93                 name += gd->reloc_off;
94                 reloc_get_dev += gd->reloc_off;
95 #endif
96                 if (strncmp(ifname, name, strlen(name)) == 0)
97                         return reloc_get_dev(dev);
98                 drvr++;
99         }
100         return NULL;
101 }
102 #else
103 block_dev_desc_t *get_dev(char* ifname, int dev)
104 {
105         return NULL;
106 }
107 #endif
108
109 #if (defined(CONFIG_CMD_IDE) || \
110      defined(CONFIG_CMD_MG_DISK) || \
111      defined(CONFIG_CMD_SATA) || \
112      defined(CONFIG_CMD_SCSI) || \
113      defined(CONFIG_CMD_USB) || \
114      defined(CONFIG_MMC) || \
115      defined(CONFIG_SYSTEMACE) )
116
117 /* ------------------------------------------------------------------------- */
118 /*
119  * reports device info to the user
120  */
121
122 #ifdef CONFIG_LBA48
123 typedef uint64_t lba512_t;
124 #else
125 typedef lbaint_t lba512_t;
126 #endif
127
128 /*
129  * Overflowless variant of (block_count * mul_by / div_by)
130  * when div_by > mul_by
131  */
132 static lba512_t lba512_muldiv (lba512_t block_count, lba512_t mul_by, lba512_t div_by)
133 {
134         lba512_t bc_quot, bc_rem;
135
136         /* x * m / d == x / d * m + (x % d) * m / d */
137         bc_quot = block_count / div_by;
138         bc_rem  = block_count - div_by * bc_quot;
139         return bc_quot * mul_by + (bc_rem * mul_by) / div_by;
140 }
141
142 void dev_print (block_dev_desc_t *dev_desc)
143 {
144         lba512_t lba512; /* number of blocks if 512bytes block size */
145
146         if (dev_desc->type == DEV_TYPE_UNKNOWN) {
147                 puts ("not available\n");
148                 return;
149         }
150
151         switch (dev_desc->if_type) {
152         case IF_TYPE_SCSI:
153                 printf ("(%d:%d) Vendor: %s Prod.: %s Rev: %s\n",
154                         dev_desc->target,dev_desc->lun,
155                         dev_desc->vendor,
156                         dev_desc->product,
157                         dev_desc->revision);
158                 break;
159         case IF_TYPE_ATAPI:
160         case IF_TYPE_IDE:
161         case IF_TYPE_SATA:
162                 printf ("Model: %s Firm: %s Ser#: %s\n",
163                         dev_desc->vendor,
164                         dev_desc->revision,
165                         dev_desc->product);
166                 break;
167         case IF_TYPE_SD:
168         case IF_TYPE_MMC:
169         case IF_TYPE_USB:
170                 printf ("Vendor: %s Rev: %s Prod: %s\n",
171                         dev_desc->vendor,
172                         dev_desc->revision,
173                         dev_desc->product);
174                 break;
175         case IF_TYPE_DOC:
176                 puts("device type DOC\n");
177                 return;
178         case IF_TYPE_UNKNOWN:
179                 puts("device type unknown\n");
180                 return;
181         default:
182                 printf("Unhandled device type: %i\n", dev_desc->if_type);
183                 return;
184         }
185         puts ("            Type: ");
186         if (dev_desc->removable)
187                 puts ("Removable ");
188         switch (dev_desc->type & 0x1F) {
189         case DEV_TYPE_HARDDISK:
190                 puts ("Hard Disk");
191                 break;
192         case DEV_TYPE_CDROM:
193                 puts ("CD ROM");
194                 break;
195         case DEV_TYPE_OPDISK:
196                 puts ("Optical Device");
197                 break;
198         case DEV_TYPE_TAPE:
199                 puts ("Tape");
200                 break;
201         default:
202                 printf ("# %02X #", dev_desc->type & 0x1F);
203                 break;
204         }
205         puts ("\n");
206         if ((dev_desc->lba * dev_desc->blksz)>0L) {
207                 ulong mb, mb_quot, mb_rem, gb, gb_quot, gb_rem;
208                 lbaint_t lba;
209
210                 lba = dev_desc->lba;
211
212                 lba512 = (lba * (dev_desc->blksz/512));
213                 /* round to 1 digit */
214                 mb = lba512_muldiv(lba512, 10, 2048);   /* 2048 = (1024 * 1024) / 512 MB */
215
216                 mb_quot = mb / 10;
217                 mb_rem  = mb - (10 * mb_quot);
218
219                 gb = mb / 1024;
220                 gb_quot = gb / 10;
221                 gb_rem  = gb - (10 * gb_quot);
222 #ifdef CONFIG_LBA48
223                 if (dev_desc->lba48)
224                         printf ("            Supports 48-bit addressing\n");
225 #endif
226 #if defined(CONFIG_SYS_64BIT_LBA)
227                 printf ("            Capacity: %ld.%ld MB = %ld.%ld GB (%Ld x %ld)\n",
228                         mb_quot, mb_rem,
229                         gb_quot, gb_rem,
230                         lba,
231                         dev_desc->blksz);
232 #else
233                 printf ("            Capacity: %ld.%ld MB = %ld.%ld GB (%ld x %ld)\n",
234                         mb_quot, mb_rem,
235                         gb_quot, gb_rem,
236                         (ulong)lba,
237                         dev_desc->blksz);
238 #endif
239         } else {
240                 puts ("            Capacity: not available\n");
241         }
242 }
243 #endif
244
245 #if (defined(CONFIG_CMD_IDE) || \
246      defined(CONFIG_CMD_MG_DISK) || \
247      defined(CONFIG_CMD_SATA) || \
248      defined(CONFIG_CMD_SCSI) || \
249      defined(CONFIG_CMD_USB) || \
250      defined(CONFIG_MMC)                || \
251      defined(CONFIG_SYSTEMACE) )
252
253 #if defined(CONFIG_MAC_PARTITION) || \
254     defined(CONFIG_DOS_PARTITION) || \
255     defined(CONFIG_ISO_PARTITION) || \
256     defined(CONFIG_AMIGA_PARTITION) || \
257     defined(CONFIG_EFI_PARTITION)
258
259 void init_part (block_dev_desc_t * dev_desc)
260 {
261 #ifdef CONFIG_ISO_PARTITION
262         if (test_part_iso(dev_desc) == 0) {
263                 dev_desc->part_type = PART_TYPE_ISO;
264                 return;
265         }
266 #endif
267
268 #ifdef CONFIG_MAC_PARTITION
269         if (test_part_mac(dev_desc) == 0) {
270                 dev_desc->part_type = PART_TYPE_MAC;
271                 return;
272         }
273 #endif
274
275 /* must be placed before DOS partition detection */
276 #ifdef CONFIG_EFI_PARTITION
277         if (test_part_efi(dev_desc) == 0) {
278                 dev_desc->part_type = PART_TYPE_EFI;
279                 return;
280         }
281 #endif
282
283 #ifdef CONFIG_DOS_PARTITION
284         if (test_part_dos(dev_desc) == 0) {
285                 dev_desc->part_type = PART_TYPE_DOS;
286                 return;
287         }
288 #endif
289
290 #ifdef CONFIG_AMIGA_PARTITION
291         if (test_part_amiga(dev_desc) == 0) {
292             dev_desc->part_type = PART_TYPE_AMIGA;
293             return;
294         }
295 #endif
296 }
297
298
299 int get_partition_info (block_dev_desc_t *dev_desc, int part
300                                         , disk_partition_t *info)
301 {
302         switch (dev_desc->part_type) {
303 #ifdef CONFIG_MAC_PARTITION
304         case PART_TYPE_MAC:
305                 if (get_partition_info_mac(dev_desc,part,info) == 0) {
306                         PRINTF ("## Valid MAC partition found ##\n");
307                         return (0);
308                 }
309                 break;
310 #endif
311
312 #ifdef CONFIG_DOS_PARTITION
313         case PART_TYPE_DOS:
314                 if (get_partition_info_dos(dev_desc,part,info) == 0) {
315                         PRINTF ("## Valid DOS partition found ##\n");
316                         return (0);
317                 }
318                 break;
319 #endif
320
321 #ifdef CONFIG_ISO_PARTITION
322         case PART_TYPE_ISO:
323                 if (get_partition_info_iso(dev_desc,part,info) == 0) {
324                         PRINTF ("## Valid ISO boot partition found ##\n");
325                         return (0);
326                 }
327                 break;
328 #endif
329
330 #ifdef CONFIG_AMIGA_PARTITION
331         case PART_TYPE_AMIGA:
332             if (get_partition_info_amiga(dev_desc, part, info) == 0)
333             {
334                 PRINTF ("## Valid Amiga partition found ##\n");
335                 return (0);
336             }
337             break;
338 #endif
339
340 #ifdef CONFIG_EFI_PARTITION
341         case PART_TYPE_EFI:
342                 if (get_partition_info_efi(dev_desc,part,info) == 0) {
343                         PRINTF ("## Valid EFI partition found ##\n");
344                         return (0);
345                 }
346                 break;
347 #endif
348         default:
349                 break;
350         }
351         return (-1);
352 }
353
354 int get_partition_info_with_partnum (block_dev_desc_t *dev_desc, int part
355                 , disk_partition_t *info, unsigned long total,unsigned long sdidx, int sdpart, disk_partition_t *sdinfo)
356 {
357         switch (dev_desc->part_type) {
358 #ifdef CONFIG_MAC_PARTITION
359         case PART_TYPE_MAC:
360                 if (get_partition_info_mac(dev_desc,part,info) == 0) {
361                         PRINTF ("## Valid MAC partition found ##\n");
362                         return (0);
363                 }
364                 break;
365 #endif
366
367 #ifdef CONFIG_DOS_PARTITION
368         case PART_TYPE_DOS:
369                 if (get_partition_info_dos(dev_desc,part,info) == 0) {
370                         PRINTF ("## Valid DOS partition found ##\n");
371                         return (0);
372                 }
373                 break;
374 #endif
375
376 #ifdef CONFIG_ISO_PARTITION
377         case PART_TYPE_ISO:
378                 if (get_partition_info_iso(dev_desc,part,info) == 0) {
379                         PRINTF ("## Valid ISO boot partition found ##\n");
380                         return (0);
381                 }
382                 break;
383 #endif
384
385 #ifdef CONFIG_AMIGA_PARTITION
386         case PART_TYPE_AMIGA:
387             if (get_partition_info_amiga(dev_desc, part, info) == 0)
388             {
389                 PRINTF ("## Valid Amiga partition found ##\n");
390                 return (0);
391             }
392             break;
393 #endif
394
395 #ifdef CONFIG_EFI_PARTITION
396         case PART_TYPE_EFI:
397                 if (get_partition_info_efi_with_partnum(dev_desc,part,info, total, sdidx, sdpart, sdinfo) == 0) {
398                         PRINTF ("## Valid EFI partition found ##\n");
399                         return (0);
400                 }
401                 break;
402 #endif
403         default:
404                 break;
405         }
406         return (-1);
407 }
408
409 int get_all_partition_info (block_dev_desc_t *dev_desc, PARTITION_CFG *info, unsigned int *total_partition_num)
410 {
411         switch(dev_desc->part_type){
412 #ifdef CONFIG_EFI_PARTITION
413         case PART_TYPE_EFI:
414                 if (get_all_partition_info_efi(dev_desc,info,total_partition_num) == 0) {
415                         PRINTF ("## Get All EFI partition  ##\n");
416                         return (0);
417                 }
418                 break;
419 #endif
420         default:
421                 break;
422         }
423         return (-1);
424 }
425
426 int get_partition_info_by_name (block_dev_desc_t *dev_desc, wchar_t* partition_name,
427                                                 disk_partition_t *info)
428 {
429         switch(dev_desc->part_type){
430 #ifdef CONFIG_EFI_PARTITION
431         case PART_TYPE_EFI:
432                 if (get_partition_info_by_name_efi(dev_desc, partition_name, info)== 0) {
433                         PRINTF ("## Valid EFI partition found ##\n");
434                         return (0);
435                 }
436                 break;
437 #endif
438         default:
439                 break;
440         }
441         return (-1);
442 }
443
444 int get_partition_num_by_name(block_dev_desc_t *dev_desc, const char *partition_name)
445 {
446         int ret = -1;
447
448         switch(dev_desc->part_type){
449 #ifdef CONFIG_EFI_PARTITION
450         case PART_TYPE_EFI:
451                 ret = get_partition_num_by_name_efi(dev_desc, partition_name);
452                 break;
453 #endif
454         default:
455                 break;
456         }
457
458         return ret;
459 }
460
461 static void print_part_header (const char *type, block_dev_desc_t * dev_desc)
462 {
463         puts ("\nPartition Map for ");
464         switch (dev_desc->if_type) {
465         case IF_TYPE_IDE:
466                 puts ("IDE");
467                 break;
468         case IF_TYPE_SATA:
469                 puts ("SATA");
470                 break;
471         case IF_TYPE_SCSI:
472                 puts ("SCSI");
473                 break;
474         case IF_TYPE_ATAPI:
475                 puts ("ATAPI");
476                 break;
477         case IF_TYPE_USB:
478                 puts ("USB");
479                 break;
480         case IF_TYPE_DOC:
481                 puts ("DOC");
482                 break;
483         case IF_TYPE_MMC:
484                 puts ("MMC");
485                 break;
486         default:
487                 puts ("UNKNOWN");
488                 break;
489         }
490         printf (" device %d  --   Partition Type: %s\n\n",
491                         dev_desc->dev, type);
492 }
493
494 void print_part (block_dev_desc_t * dev_desc)
495 {
496
497                 switch (dev_desc->part_type) {
498 #ifdef CONFIG_MAC_PARTITION
499         case PART_TYPE_MAC:
500                 PRINTF ("## Testing for valid MAC partition ##\n");
501                 print_part_header ("MAC", dev_desc);
502                 print_part_mac (dev_desc);
503                 return;
504 #endif
505 #ifdef CONFIG_DOS_PARTITION
506         case PART_TYPE_DOS:
507                 PRINTF ("## Testing for valid DOS partition ##\n");
508                 print_part_header ("DOS", dev_desc);
509                 print_part_dos (dev_desc);
510                 return;
511 #endif
512
513 #ifdef CONFIG_ISO_PARTITION
514         case PART_TYPE_ISO:
515                 PRINTF ("## Testing for valid ISO Boot partition ##\n");
516                 print_part_header ("ISO", dev_desc);
517                 print_part_iso (dev_desc);
518                 return;
519 #endif
520
521 #ifdef CONFIG_AMIGA_PARTITION
522         case PART_TYPE_AMIGA:
523             PRINTF ("## Testing for a valid Amiga partition ##\n");
524             print_part_header ("AMIGA", dev_desc);
525             print_part_amiga (dev_desc);
526             return;
527 #endif
528
529 #ifdef CONFIG_EFI_PARTITION
530         case PART_TYPE_EFI:
531                 PRINTF ("## Testing for valid EFI partition ##\n");
532                 print_part_header ("EFI", dev_desc);
533                 print_part_efi (dev_desc);
534                 return;
535 #endif
536         }
537         puts ("## Unknown partition table\n");
538 }
539
540
541 #else   /* neither MAC nor DOS nor ISO nor AMIGA nor EFI partition configured */
542 # error neither CONFIG_MAC_PARTITION nor CONFIG_DOS_PARTITION
543 # error nor CONFIG_ISO_PARTITION nor CONFIG_AMIGA_PARTITION
544 # error nor CONFIG_EFI_PARTITION configured!
545 #endif
546
547 #endif