Blame view

disk/part.c 13.7 KB
affae2bff   wdenk   Initial revision
1
2
3
4
  /*
   * (C) Copyright 2001
   * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
   *
1a4596601   Wolfgang Denk   Add GPL-2.0+ SPDX...
5
   * SPDX-License-Identifier:	GPL-2.0+
affae2bff   wdenk   Initial revision
6
7
8
9
10
   */
  
  #include <common.h>
  #include <command.h>
  #include <ide.h>
10a37fd7a   Stephen Warren   disk: get_device_...
11
  #include <malloc.h>
735dd97b1   Grant Likely   [PATCH 1_4] Merge...
12
  #include <part.h>
affae2bff   wdenk   Initial revision
13
14
15
16
17
18
19
20
  
  #undef	PART_DEBUG
  
  #ifdef	PART_DEBUG
  #define	PRINTF(fmt,args...)	printf (fmt ,##args)
  #else
  #define PRINTF(fmt,args...)
  #endif
735dd97b1   Grant Likely   [PATCH 1_4] Merge...
21
22
23
24
25
26
  struct block_drvr {
  	char *name;
  	block_dev_desc_t* (*get_dev)(int dev);
  };
  
  static const struct block_drvr block_drvr[] = {
cde5c64d1   Jon Loeliger   disk/: Remove obs...
27
  #if defined(CONFIG_CMD_IDE)
735dd97b1   Grant Likely   [PATCH 1_4] Merge...
28
29
  	{ .name = "ide", .get_dev = ide_get_dev, },
  #endif
c7057b529   Dave Liu   ata: add the supp...
30
31
32
  #if defined(CONFIG_CMD_SATA)
  	{.name = "sata", .get_dev = sata_get_dev, },
  #endif
cde5c64d1   Jon Loeliger   disk/: Remove obs...
33
  #if defined(CONFIG_CMD_SCSI)
735dd97b1   Grant Likely   [PATCH 1_4] Merge...
34
35
  	{ .name = "scsi", .get_dev = scsi_get_dev, },
  #endif
cde5c64d1   Jon Loeliger   disk/: Remove obs...
36
  #if defined(CONFIG_CMD_USB) && defined(CONFIG_USB_STORAGE)
735dd97b1   Grant Likely   [PATCH 1_4] Merge...
37
38
39
40
41
42
43
44
  	{ .name = "usb", .get_dev = usb_stor_get_dev, },
  #endif
  #if defined(CONFIG_MMC)
  	{ .name = "mmc", .get_dev = mmc_get_dev, },
  #endif
  #if defined(CONFIG_SYSTEMACE)
  	{ .name = "ace", .get_dev = systemace_get_dev, },
  #endif
f4d8de48f   Henrik Nordström   sandbox: block dr...
45
46
47
  #if defined(CONFIG_SANDBOX)
  	{ .name = "host", .get_dev = host_get_dev, },
  #endif
735dd97b1   Grant Likely   [PATCH 1_4] Merge...
48
49
  	{ },
  };
751bb5710   Stefan Roese   [PATCH] Fix reloc...
50
  DECLARE_GLOBAL_DATA_PTR;
751bb5710   Stefan Roese   [PATCH] Fix reloc...
51

0c9c8fb5e   Gabe Black   disk: Make the di...
52
  #ifdef HAVE_BLOCK_DEVICE
99d2c205d   Rob Herring   disk/part: introd...
53
  block_dev_desc_t *get_dev(const char *ifname, int dev)
735dd97b1   Grant Likely   [PATCH 1_4] Merge...
54
55
  {
  	const struct block_drvr *drvr = block_drvr;
6c7cac8c4   Stefan Roese   [PATCH] get_dev()...
56
  	block_dev_desc_t* (*reloc_get_dev)(int dev);
23090dacd   Heiko Schocher   disk/part.c: fix ...
57
  	char *name;
735dd97b1   Grant Likely   [PATCH 1_4] Merge...
58

7e71dc688   Tim Kientzle   disk/part.c: Fix ...
59
60
  	if (!ifname)
  		return NULL;
23090dacd   Heiko Schocher   disk/part.c: fix ...
61
  	name = drvr->name;
2e5167cca   Wolfgang Denk   Replace CONFIG_RE...
62
  #ifdef CONFIG_NEEDS_MANUAL_RELOC
23090dacd   Heiko Schocher   disk/part.c: fix ...
63
64
  	name += gd->reloc_off;
  #endif
b16aadf41   Lei Wen   disk/part.c: fix ...
65
  	while (drvr->name) {
23090dacd   Heiko Schocher   disk/part.c: fix ...
66
  		name = drvr->name;
521af04d8   Peter Tyser   Conditionally per...
67
  		reloc_get_dev = drvr->get_dev;
2e5167cca   Wolfgang Denk   Replace CONFIG_RE...
68
  #ifdef CONFIG_NEEDS_MANUAL_RELOC
23090dacd   Heiko Schocher   disk/part.c: fix ...
69
  		name += gd->reloc_off;
521af04d8   Peter Tyser   Conditionally per...
70
71
  		reloc_get_dev += gd->reloc_off;
  #endif
23090dacd   Heiko Schocher   disk/part.c: fix ...
72
  		if (strncmp(ifname, name, strlen(name)) == 0)
751bb5710   Stefan Roese   [PATCH] Fix reloc...
73
  			return reloc_get_dev(dev);
735dd97b1   Grant Likely   [PATCH 1_4] Merge...
74
75
76
77
78
  		drvr++;
  	}
  	return NULL;
  }
  #else
99d2c205d   Rob Herring   disk/part: introd...
79
  block_dev_desc_t *get_dev(const char *ifname, int dev)
735dd97b1   Grant Likely   [PATCH 1_4] Merge...
80
81
82
83
  {
  	return NULL;
  }
  #endif
0c9c8fb5e   Gabe Black   disk: Make the di...
84
  #ifdef HAVE_BLOCK_DEVICE
735dd97b1   Grant Likely   [PATCH 1_4] Merge...
85

affae2bff   wdenk   Initial revision
86
87
88
89
  /* ------------------------------------------------------------------------- */
  /*
   * reports device info to the user
   */
69a2a4d9a   Sergei Trofimovich   disk/part.c: 'usb...
90

42dfe7a18   wdenk   Code cleanup; mak...
91
  #ifdef CONFIG_LBA48
69a2a4d9a   Sergei Trofimovich   disk/part.c: 'usb...
92
  typedef uint64_t lba512_t;
c40b29568   wdenk   * Patch by Rune T...
93
  #else
69a2a4d9a   Sergei Trofimovich   disk/part.c: 'usb...
94
  typedef lbaint_t lba512_t;
c40b29568   wdenk   * Patch by Rune T...
95
  #endif
affae2bff   wdenk   Initial revision
96

69a2a4d9a   Sergei Trofimovich   disk/part.c: 'usb...
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
  /*
   * Overflowless variant of (block_count * mul_by / div_by)
   * when div_by > mul_by
   */
  static lba512_t lba512_muldiv (lba512_t block_count, lba512_t mul_by, lba512_t div_by)
  {
  	lba512_t bc_quot, bc_rem;
  
  	/* x * m / d == x / d * m + (x % d) * m / d */
  	bc_quot = block_count / div_by;
  	bc_rem  = block_count - div_by * bc_quot;
  	return bc_quot * mul_by + (bc_rem * mul_by) / div_by;
  }
  
  void dev_print (block_dev_desc_t *dev_desc)
  {
  	lba512_t lba512; /* number of blocks if 512bytes block size */
af75a45d2   Wolfgang Denk   IDE: bail out of ...
114
115
116
117
118
  	if (dev_desc->type == DEV_TYPE_UNKNOWN) {
  		puts ("not available
  ");
  		return;
  	}
8ec6e332e   Tor Krill   Fix incorrect swi...
119
  	switch (dev_desc->if_type) {
574b31951   Detlev Zundel   Fix disk type out...
120
121
122
123
  	case IF_TYPE_SCSI:
  		printf ("(%d:%d) Vendor: %s Prod.: %s Rev: %s
  ",
  			dev_desc->target,dev_desc->lun,
affae2bff   wdenk   Initial revision
124
  			dev_desc->vendor,
574b31951   Detlev Zundel   Fix disk type out...
125
126
127
  			dev_desc->product,
  			dev_desc->revision);
  		break;
6e24a1eb1   Remy Bohmer   Add missing devic...
128
  	case IF_TYPE_ATAPI:
574b31951   Detlev Zundel   Fix disk type out...
129
130
  	case IF_TYPE_IDE:
  	case IF_TYPE_SATA:
c7057b529   Dave Liu   ata: add the supp...
131
132
133
134
135
  		printf ("Model: %s Firm: %s Ser#: %s
  ",
  			dev_desc->vendor,
  			dev_desc->revision,
  			dev_desc->product);
574b31951   Detlev Zundel   Fix disk type out...
136
  		break;
6e24a1eb1   Remy Bohmer   Add missing devic...
137
138
  	case IF_TYPE_SD:
  	case IF_TYPE_MMC:
47bebe34c   Nícolas Carneiro Lebedenco   Fix dev_print whe...
139
140
141
142
143
144
145
  	case IF_TYPE_USB:
  		printf ("Vendor: %s Rev: %s Prod: %s
  ",
  			dev_desc->vendor,
  			dev_desc->revision,
  			dev_desc->product);
  		break;
6e24a1eb1   Remy Bohmer   Add missing devic...
146
147
148
149
  	case IF_TYPE_DOC:
  		puts("device type DOC
  ");
  		return;
8ec6e332e   Tor Krill   Fix incorrect swi...
150
  	case IF_TYPE_UNKNOWN:
6e24a1eb1   Remy Bohmer   Add missing devic...
151
152
153
  		puts("device type unknown
  ");
  		return;
574b31951   Detlev Zundel   Fix disk type out...
154
  	default:
6e24a1eb1   Remy Bohmer   Add missing devic...
155
156
  		printf("Unhandled device type: %i
  ", dev_desc->if_type);
574b31951   Detlev Zundel   Fix disk type out...
157
  		return;
affae2bff   wdenk   Initial revision
158
159
160
161
162
  	}
  	puts ("            Type: ");
  	if (dev_desc->removable)
  		puts ("Removable ");
  	switch (dev_desc->type & 0x1F) {
726c0f1e5   Detlev Zundel   cosmetic: Adjust ...
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
  	case DEV_TYPE_HARDDISK:
  		puts ("Hard Disk");
  		break;
  	case DEV_TYPE_CDROM:
  		puts ("CD ROM");
  		break;
  	case DEV_TYPE_OPDISK:
  		puts ("Optical Device");
  		break;
  	case DEV_TYPE_TAPE:
  		puts ("Tape");
  		break;
  	default:
  		printf ("# %02X #", dev_desc->type & 0x1F);
  		break;
affae2bff   wdenk   Initial revision
178
179
180
  	}
  	puts ("
  ");
33699df12   Jerry Huang   part: check each ...
181
  	if (dev_desc->lba > 0L && dev_desc->blksz > 0L) {
affae2bff   wdenk   Initial revision
182
  		ulong mb, mb_quot, mb_rem, gb, gb_quot, gb_rem;
c40b29568   wdenk   * Patch by Rune T...
183
  		lbaint_t lba;
6e5923851   wdenk   * Cleanup, minor ...
184
185
  
  		lba = dev_desc->lba;
affae2bff   wdenk   Initial revision
186

c40b29568   wdenk   * Patch by Rune T...
187
  		lba512 = (lba * (dev_desc->blksz/512));
affae2bff   wdenk   Initial revision
188
  		/* round to 1 digit */
69a2a4d9a   Sergei Trofimovich   disk/part.c: 'usb...
189
  		mb = lba512_muldiv(lba512, 10, 2048);	/* 2048 = (1024 * 1024) / 512 MB */
affae2bff   wdenk   Initial revision
190
191
192
193
194
195
  		mb_quot	= mb / 10;
  		mb_rem	= mb - (10 * mb_quot);
  
  		gb = mb / 1024;
  		gb_quot	= gb / 10;
  		gb_rem	= gb - (10 * gb_quot);
42dfe7a18   wdenk   Code cleanup; mak...
196
  #ifdef CONFIG_LBA48
6e5923851   wdenk   * Cleanup, minor ...
197
  		if (dev_desc->lba48)
c40b29568   wdenk   * Patch by Rune T...
198
199
200
  			printf ("            Supports 48-bit addressing
  ");
  #endif
4b142febf   Heiko Schocher   common: delete CO...
201
  #if defined(CONFIG_SYS_64BIT_LBA)
6c6166f52   Mike Frysinger   vsprintf: pull up...
202
203
  		printf ("            Capacity: %ld.%ld MB = %ld.%ld GB (%Ld x %ld)
  ",
c40b29568   wdenk   * Patch by Rune T...
204
205
206
207
208
  			mb_quot, mb_rem,
  			gb_quot, gb_rem,
  			lba,
  			dev_desc->blksz);
  #else
affae2bff   wdenk   Initial revision
209
210
211
212
  		printf ("            Capacity: %ld.%ld MB = %ld.%ld GB (%ld x %ld)
  ",
  			mb_quot, mb_rem,
  			gb_quot, gb_rem,
c40b29568   wdenk   * Patch by Rune T...
213
  			(ulong)lba,
affae2bff   wdenk   Initial revision
214
  			dev_desc->blksz);
c40b29568   wdenk   * Patch by Rune T...
215
  #endif
affae2bff   wdenk   Initial revision
216
217
218
219
220
  	} else {
  		puts ("            Capacity: not available
  ");
  	}
  }
b3aff0cb9   Jon Loeliger   disk/ doc/ lib_*/...
221
  #endif
affae2bff   wdenk   Initial revision
222

0c9c8fb5e   Gabe Black   disk: Make the di...
223
  #ifdef HAVE_BLOCK_DEVICE
affae2bff   wdenk   Initial revision
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
  
  void init_part (block_dev_desc_t * dev_desc)
  {
  #ifdef CONFIG_ISO_PARTITION
  	if (test_part_iso(dev_desc) == 0) {
  		dev_desc->part_type = PART_TYPE_ISO;
  		return;
  	}
  #endif
  
  #ifdef CONFIG_MAC_PARTITION
  	if (test_part_mac(dev_desc) == 0) {
  		dev_desc->part_type = PART_TYPE_MAC;
  		return;
  	}
  #endif
07f3d789b   richardretanubun   Add support for C...
240
241
242
243
244
245
246
  /* must be placed before DOS partition detection */
  #ifdef CONFIG_EFI_PARTITION
  	if (test_part_efi(dev_desc) == 0) {
  		dev_desc->part_type = PART_TYPE_EFI;
  		return;
  	}
  #endif
affae2bff   wdenk   Initial revision
247
248
249
250
251
252
  #ifdef CONFIG_DOS_PARTITION
  	if (test_part_dos(dev_desc) == 0) {
  		dev_desc->part_type = PART_TYPE_DOS;
  		return;
  	}
  #endif
c7de829c7   wdenk   * Patch by Thomas...
253
254
255
256
257
258
259
  
  #ifdef CONFIG_AMIGA_PARTITION
  	if (test_part_amiga(dev_desc) == 0) {
  	    dev_desc->part_type = PART_TYPE_AMIGA;
  	    return;
  	}
  #endif
99d2c205d   Rob Herring   disk/part: introd...
260
  	dev_desc->part_type = PART_TYPE_UNKNOWN;
affae2bff   wdenk   Initial revision
261
  }
0c9c8fb5e   Gabe Black   disk: Make the di...
262
263
264
265
266
  #if defined(CONFIG_MAC_PARTITION) || \
  	defined(CONFIG_DOS_PARTITION) || \
  	defined(CONFIG_ISO_PARTITION) || \
  	defined(CONFIG_AMIGA_PARTITION) || \
  	defined(CONFIG_EFI_PARTITION)
affae2bff   wdenk   Initial revision
267
268
269
270
271
  static void print_part_header (const char *type, block_dev_desc_t * dev_desc)
  {
  	puts ("
  Partition Map for ");
  	switch (dev_desc->if_type) {
726c0f1e5   Detlev Zundel   cosmetic: Adjust ...
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
  	case IF_TYPE_IDE:
  		puts ("IDE");
  		break;
  	case IF_TYPE_SATA:
  		puts ("SATA");
  		break;
  	case IF_TYPE_SCSI:
  		puts ("SCSI");
  		break;
  	case IF_TYPE_ATAPI:
  		puts ("ATAPI");
  		break;
  	case IF_TYPE_USB:
  		puts ("USB");
  		break;
  	case IF_TYPE_DOC:
  		puts ("DOC");
  		break;
8f3b96427   Lei Wen   mmc: print out pa...
290
291
292
  	case IF_TYPE_MMC:
  		puts ("MMC");
  		break;
f4d8de48f   Henrik Nordström   sandbox: block dr...
293
294
295
  	case IF_TYPE_HOST:
  		puts("HOST");
  		break;
726c0f1e5   Detlev Zundel   cosmetic: Adjust ...
296
297
298
  	default:
  		puts ("UNKNOWN");
  		break;
affae2bff   wdenk   Initial revision
299
300
301
302
303
304
  	}
  	printf (" device %d  --   Partition Type: %s
  
  ",
  			dev_desc->dev, type);
  }
0c9c8fb5e   Gabe Black   disk: Make the di...
305
  #endif /* any CONFIG_..._PARTITION */
affae2bff   wdenk   Initial revision
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
  void print_part (block_dev_desc_t * dev_desc)
  {
  
  		switch (dev_desc->part_type) {
  #ifdef CONFIG_MAC_PARTITION
  	case PART_TYPE_MAC:
  		PRINTF ("## Testing for valid MAC partition ##
  ");
  		print_part_header ("MAC", dev_desc);
  		print_part_mac (dev_desc);
  		return;
  #endif
  #ifdef CONFIG_DOS_PARTITION
  	case PART_TYPE_DOS:
  		PRINTF ("## Testing for valid DOS partition ##
  ");
  		print_part_header ("DOS", dev_desc);
  		print_part_dos (dev_desc);
  		return;
  #endif
  
  #ifdef CONFIG_ISO_PARTITION
  	case PART_TYPE_ISO:
  		PRINTF ("## Testing for valid ISO Boot partition ##
  ");
  		print_part_header ("ISO", dev_desc);
  		print_part_iso (dev_desc);
  		return;
  #endif
c7de829c7   wdenk   * Patch by Thomas...
335
336
337
338
339
340
341
342
343
  
  #ifdef CONFIG_AMIGA_PARTITION
  	case PART_TYPE_AMIGA:
  	    PRINTF ("## Testing for a valid Amiga partition ##
  ");
  	    print_part_header ("AMIGA", dev_desc);
  	    print_part_amiga (dev_desc);
  	    return;
  #endif
07f3d789b   richardretanubun   Add support for C...
344
345
346
347
348
349
350
351
352
  
  #ifdef CONFIG_EFI_PARTITION
  	case PART_TYPE_EFI:
  		PRINTF ("## Testing for valid EFI partition ##
  ");
  		print_part_header ("EFI", dev_desc);
  		print_part_efi (dev_desc);
  		return;
  #endif
affae2bff   wdenk   Initial revision
353
354
355
356
  	}
  	puts ("## Unknown partition table
  ");
  }
0c9c8fb5e   Gabe Black   disk: Make the di...
357
  #endif /* HAVE_BLOCK_DEVICE */
2f5016462   Stephen Warren   disk: make get_pa...
358
359
360
361
  
  int get_partition_info(block_dev_desc_t *dev_desc, int part
  					, disk_partition_t *info)
  {
0c9c8fb5e   Gabe Black   disk: Make the di...
362
  #ifdef HAVE_BLOCK_DEVICE
2f5016462   Stephen Warren   disk: make get_pa...
363

894bfbbfb   Stephen Warren   disk: part_efi: p...
364
365
366
367
  #ifdef CONFIG_PARTITION_UUIDS
  	/* The common case is no UUID support */
  	info->uuid[0] = 0;
  #endif
2f5016462   Stephen Warren   disk: make get_pa...
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
  	switch (dev_desc->part_type) {
  #ifdef CONFIG_MAC_PARTITION
  	case PART_TYPE_MAC:
  		if (get_partition_info_mac(dev_desc, part, info) == 0) {
  			PRINTF("## Valid MAC partition found ##
  ");
  			return 0;
  		}
  		break;
  #endif
  
  #ifdef CONFIG_DOS_PARTITION
  	case PART_TYPE_DOS:
  		if (get_partition_info_dos(dev_desc, part, info) == 0) {
  			PRINTF("## Valid DOS partition found ##
  ");
  			return 0;
  		}
  		break;
  #endif
  
  #ifdef CONFIG_ISO_PARTITION
  	case PART_TYPE_ISO:
  		if (get_partition_info_iso(dev_desc, part, info) == 0) {
  			PRINTF("## Valid ISO boot partition found ##
  ");
  			return 0;
  		}
  		break;
  #endif
  
  #ifdef CONFIG_AMIGA_PARTITION
  	case PART_TYPE_AMIGA:
  		if (get_partition_info_amiga(dev_desc, part, info) == 0) {
  			PRINTF("## Valid Amiga partition found ##
  ");
  			return 0;
  		}
  		break;
  #endif
  
  #ifdef CONFIG_EFI_PARTITION
  	case PART_TYPE_EFI:
  		if (get_partition_info_efi(dev_desc, part, info) == 0) {
  			PRINTF("## Valid EFI partition found ##
  ");
  			return 0;
  		}
  		break;
  #endif
  	default:
  		break;
  	}
0c9c8fb5e   Gabe Black   disk: Make the di...
421
  #endif /* HAVE_BLOCK_DEVICE */
2f5016462   Stephen Warren   disk: make get_pa...
422
423
424
  
  	return -1;
  }
99d2c205d   Rob Herring   disk/part: introd...
425

2023e6086   Stephen Warren   disk: introduce g...
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
  int get_device(const char *ifname, const char *dev_str,
  	       block_dev_desc_t **dev_desc)
  {
  	char *ep;
  	int dev;
  
  	dev = simple_strtoul(dev_str, &ep, 16);
  	if (*ep) {
  		printf("** Bad device specification %s %s **
  ",
  		       ifname, dev_str);
  		return -1;
  	}
  
  	*dev_desc = get_dev(ifname, dev);
  	if (!(*dev_desc) || ((*dev_desc)->type == DEV_TYPE_UNKNOWN)) {
  		printf("** Bad device %s %s **
  ", ifname, dev_str);
  		return -1;
  	}
  
  	return dev;
  }
10a37fd7a   Stephen Warren   disk: get_device_...
449
450
451
452
  #define PART_UNSPECIFIED -2
  #define PART_AUTO -1
  #define MAX_SEARCH_PARTITIONS 16
  int get_device_and_partition(const char *ifname, const char *dev_part_str,
99d2c205d   Rob Herring   disk/part: introd...
453
  			     block_dev_desc_t **dev_desc,
10a37fd7a   Stephen Warren   disk: get_device_...
454
  			     disk_partition_t *info, int allow_whole_dev)
99d2c205d   Rob Herring   disk/part: introd...
455
  {
10a37fd7a   Stephen Warren   disk: get_device_...
456
457
458
459
  	int ret = -1;
  	const char *part_str;
  	char *dup_str = NULL;
  	const char *dev_str;
99d2c205d   Rob Herring   disk/part: introd...
460
  	int dev;
10a37fd7a   Stephen Warren   disk: get_device_...
461
462
463
464
  	char *ep;
  	int p;
  	int part;
  	disk_partition_t tmpinfo;
92ccc96bf   Simon Glass   sandbox: Add host...
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
  	/*
  	 * For now, we have a special case for sandbox, since there is no
  	 * real block device support.
  	 */
  	if (0 == strcmp(ifname, "host")) {
  		*dev_desc = NULL;
  		info->start = info->size =  info->blksz = 0;
  		info->bootable = 0;
  		strcpy((char *)info->type, BOOT_PART_TYPE);
  		strcpy((char *)info->name, "Sandbox host");
  #ifdef CONFIG_PARTITION_UUIDS
  		info->uuid[0] = 0;
  #endif
  
  		return 0;
  	}
10a37fd7a   Stephen Warren   disk: get_device_...
481
  	/* If no dev_part_str, use bootdevice environment variable */
a10973e7f   Stephen Warren   disk: allow - or ...
482
483
  	if (!dev_part_str || !strlen(dev_part_str) ||
  	    !strcmp(dev_part_str, "-"))
10a37fd7a   Stephen Warren   disk: get_device_...
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
  		dev_part_str = getenv("bootdevice");
  
  	/* If still no dev_part_str, it's an error */
  	if (!dev_part_str) {
  		printf("** No device specified **
  ");
  		goto cleanup;
  	}
  
  	/* Separate device and partition ID specification */
  	part_str = strchr(dev_part_str, ':');
  	if (part_str) {
  		dup_str = strdup(dev_part_str);
  		dup_str[part_str - dev_part_str] = 0;
  		dev_str = dup_str;
  		part_str++;
  	} else {
  		dev_str = dev_part_str;
99d2c205d   Rob Herring   disk/part: introd...
502
  	}
10a37fd7a   Stephen Warren   disk: get_device_...
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
  	/* Look up the device */
  	dev = get_device(ifname, dev_str, dev_desc);
  	if (dev < 0)
  		goto cleanup;
  
  	/* Convert partition ID string to number */
  	if (!part_str || !*part_str) {
  		part = PART_UNSPECIFIED;
  	} else if (!strcmp(part_str, "auto")) {
  		part = PART_AUTO;
  	} else {
  		/* Something specified -> use exactly that */
  		part = (int)simple_strtoul(part_str, &ep, 16);
  		/*
  		 * Less than whole string converted,
  		 * or request for whole device, but caller requires partition.
  		 */
  		if (*ep || (part == 0 && !allow_whole_dev)) {
  			printf("** Bad partition specification %s %s **
  ",
  			    ifname, dev_part_str);
  			goto cleanup;
  		}
  	}
  
  	/*
  	 * No partition table on device,
  	 * or user requested partition 0 (entire device).
  	 */
  	if (((*dev_desc)->part_type == PART_TYPE_UNKNOWN) ||
  	    (part == 0)) {
  		if (!(*dev_desc)->lba) {
  			printf("** Bad device size - %s %s **
  ", ifname,
  			       dev_str);
  			goto cleanup;
  		}
99d2c205d   Rob Herring   disk/part: introd...
540

10a37fd7a   Stephen Warren   disk: get_device_...
541
542
543
544
545
546
547
548
549
550
  		/*
  		 * If user specified a partition ID other than 0,
  		 * or the calling command only accepts partitions,
  		 * it's an error.
  		 */
  		if ((part > 0) || (!allow_whole_dev)) {
  			printf("** No partition table - %s %s **
  ", ifname,
  			       dev_str);
  			goto cleanup;
99d2c205d   Rob Herring   disk/part: introd...
551
  		}
10a37fd7a   Stephen Warren   disk: get_device_...
552

50ffc3b64   Lan Yixun (dlan)   fs/ext4: fix log2...
553
  		(*dev_desc)->log2blksz = LOG2((*dev_desc)->blksz);
99d2c205d   Rob Herring   disk/part: introd...
554
  		info->start = 0;
10a37fd7a   Stephen Warren   disk: get_device_...
555
556
557
  		info->size = (*dev_desc)->lba;
  		info->blksz = (*dev_desc)->blksz;
  		info->bootable = 0;
6ab6a650a   Stephen Warren   disk: initialize ...
558
559
  		strcpy((char *)info->type, BOOT_PART_TYPE);
  		strcpy((char *)info->name, "Whole Disk");
10a37fd7a   Stephen Warren   disk: get_device_...
560
561
562
  #ifdef CONFIG_PARTITION_UUIDS
  		info->uuid[0] = 0;
  #endif
99d2c205d   Rob Herring   disk/part: introd...
563

10a37fd7a   Stephen Warren   disk: get_device_...
564
565
  		ret = 0;
  		goto cleanup;
99d2c205d   Rob Herring   disk/part: introd...
566
  	}
10a37fd7a   Stephen Warren   disk: get_device_...
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
  	/*
  	 * Now there's known to be a partition table,
  	 * not specifying a partition means to pick partition 1.
  	 */
  	if (part == PART_UNSPECIFIED)
  		part = 1;
  
  	/*
  	 * If user didn't specify a partition number, or did specify something
  	 * other than "auto", use that partition number directly.
  	 */
  	if (part != PART_AUTO) {
  		ret = get_partition_info(*dev_desc, part, info);
  		if (ret) {
  			printf("** Invalid partition %d **
  ", part);
  			goto cleanup;
  		}
  	} else {
  		/*
  		 * Find the first bootable partition.
  		 * If none are bootable, fall back to the first valid partition.
  		 */
  		part = 0;
  		for (p = 1; p <= MAX_SEARCH_PARTITIONS; p++) {
  			ret = get_partition_info(*dev_desc, p, info);
  			if (ret)
  				continue;
  
  			/*
  			 * First valid partition, or new better partition?
  			 * If so, save partition ID.
  			 */
  			if (!part || info->bootable)
  				part = p;
  
  			/* Best possible partition? Stop searching. */
  			if (info->bootable)
  				break;
  
  			/*
  			 * We now need to search further for best possible.
  			 * If we what we just queried was the best so far,
  			 * save the info since we over-write it next loop.
  			 */
  			if (part == p)
  				tmpinfo = *info;
  		}
  		/* If we found any acceptable partition */
  		if (part) {
  			/*
  			 * If we searched all possible partition IDs,
  			 * return the first valid partition we found.
  			 */
  			if (p == MAX_SEARCH_PARTITIONS + 1)
  				*info = tmpinfo;
10a37fd7a   Stephen Warren   disk: get_device_...
623
624
625
  		} else {
  			printf("** No valid partitions found **
  ");
71bba424a   Stephen Warren   disk: get_device_...
626
  			ret = -1;
10a37fd7a   Stephen Warren   disk: get_device_...
627
628
  			goto cleanup;
  		}
99d2c205d   Rob Herring   disk/part: introd...
629
630
631
632
633
634
  	}
  	if (strncmp((char *)info->type, BOOT_PART_TYPE, sizeof(info->type)) != 0) {
  		printf("** Invalid partition type \"%.32s\""
  			" (expect \"" BOOT_PART_TYPE "\")
  ",
  			info->type);
10a37fd7a   Stephen Warren   disk: get_device_...
635
636
  		ret  = -1;
  		goto cleanup;
99d2c205d   Rob Herring   disk/part: introd...
637
  	}
50ffc3b64   Lan Yixun (dlan)   fs/ext4: fix log2...
638
  	(*dev_desc)->log2blksz = LOG2((*dev_desc)->blksz);
10a37fd7a   Stephen Warren   disk: get_device_...
639
640
  	ret = part;
  	goto cleanup;
99d2c205d   Rob Herring   disk/part: introd...
641

10a37fd7a   Stephen Warren   disk: get_device_...
642
643
644
  cleanup:
  	free(dup_str);
  	return ret;
99d2c205d   Rob Herring   disk/part: introd...
645
  }