Blame view

disk/part.c 15.4 KB
83d290c56   Tom Rini   SPDX: Convert all...
1
  // SPDX-License-Identifier: GPL-2.0+
affae2bff   wdenk   Initial revision
2
3
4
  /*
   * (C) Copyright 2001
   * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
affae2bff   wdenk   Initial revision
5
6
7
8
   */
  
  #include <common.h>
  #include <command.h>
96e5b03c8   Simon Glass   dm: part: Convert...
9
  #include <errno.h>
affae2bff   wdenk   Initial revision
10
  #include <ide.h>
10a37fd7a   Stephen Warren   disk: get_device_...
11
  #include <malloc.h>
735dd97b1   Grant Likely   [PATCH 1_4] Merge...
12
  #include <part.h>
251cee0db   Hans de Goede   ubifs: Add generi...
13
  #include <ubifs_uboot.h>
affae2bff   wdenk   Initial revision
14
15
16
17
18
19
20
21
  
  #undef	PART_DEBUG
  
  #ifdef	PART_DEBUG
  #define	PRINTF(fmt,args...)	printf (fmt ,##args)
  #else
  #define PRINTF(fmt,args...)
  #endif
307890955   Sam Protsenko   disk: Provide API...
22
23
  /* Check all partition types */
  #define PART_TYPE_ALL		-1
d47292691   Kever Yang   disk: part: scan ...
24
  static struct part_driver *part_driver_lookup_type(struct blk_desc *dev_desc)
96e5b03c8   Simon Glass   dm: part: Convert...
25
26
27
28
29
  {
  	struct part_driver *drv =
  		ll_entry_start(struct part_driver, part_driver);
  	const int n_ents = ll_entry_count(struct part_driver, part_driver);
  	struct part_driver *entry;
d47292691   Kever Yang   disk: part: scan ...
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
  	if (dev_desc->part_type == PART_TYPE_UNKNOWN) {
  		for (entry = drv; entry != drv + n_ents; entry++) {
  			int ret;
  
  			ret = entry->test(dev_desc);
  			if (!ret) {
  				dev_desc->part_type = entry->part_type;
  				return entry;
  			}
  		}
  	} else {
  		for (entry = drv; entry != drv + n_ents; entry++) {
  			if (dev_desc->part_type == entry->part_type)
  				return entry;
  		}
96e5b03c8   Simon Glass   dm: part: Convert...
45
46
47
48
49
  	}
  
  	/* Not found */
  	return NULL;
  }
56670d6fb   Kever Yang   disk: part: use c...
50
  #ifdef CONFIG_HAVE_BLOCK_DEVICE
4101f6879   Simon Glass   dm: Drop the bloc...
51
  static struct blk_desc *get_dev_hwpart(const char *ifname, int dev, int hwpart)
735dd97b1   Grant Likely   [PATCH 1_4] Merge...
52
  {
6dd9faf8f   Simon Glass   dm: part: Drop th...
53
54
  	struct blk_desc *dev_desc;
  	int ret;
735dd97b1   Grant Likely   [PATCH 1_4] Merge...
55

6dd9faf8f   Simon Glass   dm: part: Drop th...
56
57
58
59
60
  	dev_desc = blk_get_devnum_by_typename(ifname, dev);
  	if (!dev_desc) {
  		debug("%s: No device for iface '%s', dev %d
  ", __func__,
  		      ifname, dev);
7e71dc688   Tim Kientzle   disk/part.c: Fix ...
61
  		return NULL;
735dd97b1   Grant Likely   [PATCH 1_4] Merge...
62
  	}
6dd9faf8f   Simon Glass   dm: part: Drop th...
63
64
65
66
67
68
69
70
71
  	ret = blk_dselect_hwpart(dev_desc, hwpart);
  	if (ret) {
  		debug("%s: Failed to select h/w partition: err-%d
  ", __func__,
  		      ret);
  		return NULL;
  	}
  
  	return dev_desc;
735dd97b1   Grant Likely   [PATCH 1_4] Merge...
72
  }
336b6f904   Stephen Warren   disk: support dev...
73

db1d9e78e   Simon Glass   dm: blk: Rename g...
74
  struct blk_desc *blk_get_dev(const char *ifname, int dev)
336b6f904   Stephen Warren   disk: support dev...
75
  {
ecdd57e27   Stephen Warren   disk: default to ...
76
  	return get_dev_hwpart(ifname, dev, 0);
336b6f904   Stephen Warren   disk: support dev...
77
  }
735dd97b1   Grant Likely   [PATCH 1_4] Merge...
78
  #else
4101f6879   Simon Glass   dm: Drop the bloc...
79
  struct blk_desc *get_dev_hwpart(const char *ifname, int dev, int hwpart)
336b6f904   Stephen Warren   disk: support dev...
80
81
82
  {
  	return NULL;
  }
db1d9e78e   Simon Glass   dm: blk: Rename g...
83
  struct blk_desc *blk_get_dev(const char *ifname, int dev)
735dd97b1   Grant Likely   [PATCH 1_4] Merge...
84
85
86
87
  {
  	return NULL;
  }
  #endif
1811a928c   Adam Ford   Move most CONFIG_...
88
  #ifdef CONFIG_HAVE_BLOCK_DEVICE
735dd97b1   Grant Likely   [PATCH 1_4] Merge...
89

affae2bff   wdenk   Initial revision
90
91
92
93
  /* ------------------------------------------------------------------------- */
  /*
   * reports device info to the user
   */
69a2a4d9a   Sergei Trofimovich   disk/part.c: 'usb...
94

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

69a2a4d9a   Sergei Trofimovich   disk/part.c: 'usb...
101
102
103
104
  /*
   * Overflowless variant of (block_count * mul_by / div_by)
   * when div_by > mul_by
   */
214b3f311   Pavel Machek   cleanup disk/part...
105
  static lba512_t lba512_muldiv(lba512_t block_count, lba512_t mul_by, lba512_t div_by)
69a2a4d9a   Sergei Trofimovich   disk/part.c: 'usb...
106
107
108
109
110
111
112
113
  {
  	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;
  }
4101f6879   Simon Glass   dm: Drop the bloc...
114
  void dev_print (struct blk_desc *dev_desc)
69a2a4d9a   Sergei Trofimovich   disk/part.c: 'usb...
115
116
  {
  	lba512_t lba512; /* number of blocks if 512bytes block size */
af75a45d2   Wolfgang Denk   IDE: bail out of ...
117
118
119
120
121
  	if (dev_desc->type == DEV_TYPE_UNKNOWN) {
  		puts ("not available
  ");
  		return;
  	}
8ec6e332e   Tor Krill   Fix incorrect swi...
122
  	switch (dev_desc->if_type) {
574b31951   Detlev Zundel   Fix disk type out...
123
124
125
126
  	case IF_TYPE_SCSI:
  		printf ("(%d:%d) Vendor: %s Prod.: %s Rev: %s
  ",
  			dev_desc->target,dev_desc->lun,
affae2bff   wdenk   Initial revision
127
  			dev_desc->vendor,
574b31951   Detlev Zundel   Fix disk type out...
128
129
130
  			dev_desc->product,
  			dev_desc->revision);
  		break;
6e24a1eb1   Remy Bohmer   Add missing devic...
131
  	case IF_TYPE_ATAPI:
574b31951   Detlev Zundel   Fix disk type out...
132
133
  	case IF_TYPE_IDE:
  	case IF_TYPE_SATA:
c7057b529   Dave Liu   ata: add the supp...
134
135
136
137
138
  		printf ("Model: %s Firm: %s Ser#: %s
  ",
  			dev_desc->vendor,
  			dev_desc->revision,
  			dev_desc->product);
574b31951   Detlev Zundel   Fix disk type out...
139
  		break;
6e24a1eb1   Remy Bohmer   Add missing devic...
140
141
  	case IF_TYPE_SD:
  	case IF_TYPE_MMC:
47bebe34c   NĂ­colas Carneiro Lebedenco   Fix dev_print whe...
142
  	case IF_TYPE_USB:
ffab6945e   Zhikang Zhang   dm: blk: part: Ad...
143
  	case IF_TYPE_NVME:
47bebe34c   NĂ­colas Carneiro Lebedenco   Fix dev_print whe...
144
145
146
147
148
149
  		printf ("Vendor: %s Rev: %s Prod: %s
  ",
  			dev_desc->vendor,
  			dev_desc->revision,
  			dev_desc->product);
  		break;
4ad54ec4d   Tuomas Tynkkynen   blk: Introduce IF...
150
151
152
153
  	case IF_TYPE_VIRTIO:
  		printf("%s VirtIO Block Device
  ", dev_desc->vendor);
  		break;
6e24a1eb1   Remy Bohmer   Add missing devic...
154
155
156
157
  	case IF_TYPE_DOC:
  		puts("device type DOC
  ");
  		return;
8ec6e332e   Tor Krill   Fix incorrect swi...
158
  	case IF_TYPE_UNKNOWN:
6e24a1eb1   Remy Bohmer   Add missing devic...
159
160
161
  		puts("device type unknown
  ");
  		return;
574b31951   Detlev Zundel   Fix disk type out...
162
  	default:
6e24a1eb1   Remy Bohmer   Add missing devic...
163
164
  		printf("Unhandled device type: %i
  ", dev_desc->if_type);
574b31951   Detlev Zundel   Fix disk type out...
165
  		return;
affae2bff   wdenk   Initial revision
166
167
168
169
170
  	}
  	puts ("            Type: ");
  	if (dev_desc->removable)
  		puts ("Removable ");
  	switch (dev_desc->type & 0x1F) {
726c0f1e5   Detlev Zundel   cosmetic: Adjust ...
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
  	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
186
187
188
  	}
  	puts ("
  ");
33699df12   Jerry Huang   part: check each ...
189
  	if (dev_desc->lba > 0L && dev_desc->blksz > 0L) {
affae2bff   wdenk   Initial revision
190
  		ulong mb, mb_quot, mb_rem, gb, gb_quot, gb_rem;
c40b29568   wdenk   * Patch by Rune T...
191
  		lbaint_t lba;
6e5923851   wdenk   * Cleanup, minor ...
192
193
  
  		lba = dev_desc->lba;
affae2bff   wdenk   Initial revision
194

c40b29568   wdenk   * Patch by Rune T...
195
  		lba512 = (lba * (dev_desc->blksz/512));
affae2bff   wdenk   Initial revision
196
  		/* round to 1 digit */
214b3f311   Pavel Machek   cleanup disk/part...
197
198
  		/* 2048 = (1024 * 1024) / 512 MB */
  		mb = lba512_muldiv(lba512, 10, 2048);
69a2a4d9a   Sergei Trofimovich   disk/part.c: 'usb...
199

affae2bff   wdenk   Initial revision
200
201
202
203
204
205
  		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...
206
  #ifdef CONFIG_LBA48
6e5923851   wdenk   * Cleanup, minor ...
207
  		if (dev_desc->lba48)
c40b29568   wdenk   * Patch by Rune T...
208
209
210
  			printf ("            Supports 48-bit addressing
  ");
  #endif
4b142febf   Heiko Schocher   common: delete CO...
211
  #if defined(CONFIG_SYS_64BIT_LBA)
139f7b1de   Jean-Jacques Hiblot   disk: Fixed capac...
212
213
  		printf ("            Capacity: %lu.%lu MB = %lu.%lu GB (%llu x %lu)
  ",
c40b29568   wdenk   * Patch by Rune T...
214
215
216
217
218
  			mb_quot, mb_rem,
  			gb_quot, gb_rem,
  			lba,
  			dev_desc->blksz);
  #else
139f7b1de   Jean-Jacques Hiblot   disk: Fixed capac...
219
220
  		printf ("            Capacity: %lu.%lu MB = %lu.%lu GB (%lu x %lu)
  ",
affae2bff   wdenk   Initial revision
221
222
  			mb_quot, mb_rem,
  			gb_quot, gb_rem,
c40b29568   wdenk   * Patch by Rune T...
223
  			(ulong)lba,
affae2bff   wdenk   Initial revision
224
  			dev_desc->blksz);
c40b29568   wdenk   * Patch by Rune T...
225
  #endif
affae2bff   wdenk   Initial revision
226
227
228
229
230
  	} else {
  		puts ("            Capacity: not available
  ");
  	}
  }
b3aff0cb9   Jon Loeliger   disk/ doc/ lib_*/...
231
  #endif
affae2bff   wdenk   Initial revision
232

1811a928c   Adam Ford   Move most CONFIG_...
233
  #ifdef CONFIG_HAVE_BLOCK_DEVICE
affae2bff   wdenk   Initial revision
234

3e8bd4695   Simon Glass   dm: part: Rename ...
235
  void part_init(struct blk_desc *dev_desc)
affae2bff   wdenk   Initial revision
236
  {
96e5b03c8   Simon Glass   dm: part: Convert...
237
238
239
240
  	struct part_driver *drv =
  		ll_entry_start(struct part_driver, part_driver);
  	const int n_ents = ll_entry_count(struct part_driver, part_driver);
  	struct part_driver *entry;
affae2bff   wdenk   Initial revision
241

e40cf34a2   Eric Nelson   drivers: block: a...
242
  	blkcache_invalidate(dev_desc->if_type, dev_desc->devnum);
99d2c205d   Rob Herring   disk/part: introd...
243
  	dev_desc->part_type = PART_TYPE_UNKNOWN;
96e5b03c8   Simon Glass   dm: part: Convert...
244
245
246
247
248
249
250
251
252
253
254
  	for (entry = drv; entry != drv + n_ents; entry++) {
  		int ret;
  
  		ret = entry->test(dev_desc);
  		debug("%s: try '%s': ret=%d
  ", __func__, entry->name, ret);
  		if (!ret) {
  			dev_desc->part_type = entry->part_type;
  			break;
  		}
  	}
affae2bff   wdenk   Initial revision
255
  }
96e5b03c8   Simon Glass   dm: part: Convert...
256
257
  static void print_part_header(const char *type, struct blk_desc *dev_desc)
  {
f18fa31cd   Patrick Delaunay   disk: convert CON...
258
  #if CONFIG_IS_ENABLED(MAC_PARTITION) || \
b0cf73393   Patrick Delaunay   disk: convert CON...
259
  	CONFIG_IS_ENABLED(DOS_PARTITION) || \
1acc00878   Patrick Delaunay   disk: convert CON...
260
  	CONFIG_IS_ENABLED(ISO_PARTITION) || \
863c5b6cd   Patrick Delaunay   disk: convert CON...
261
  	CONFIG_IS_ENABLED(AMIGA_PARTITION) || \
bd42a9426   Patrick Delaunay   disk: convert CON...
262
  	CONFIG_IS_ENABLED(EFI_PARTITION)
affae2bff   wdenk   Initial revision
263
264
265
  	puts ("
  Partition Map for ");
  	switch (dev_desc->if_type) {
726c0f1e5   Detlev Zundel   cosmetic: Adjust ...
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
  	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...
284
285
286
  	case IF_TYPE_MMC:
  		puts ("MMC");
  		break;
f4d8de48f   Henrik Nordström   sandbox: block dr...
287
  	case IF_TYPE_HOST:
ffab6945e   Zhikang Zhang   dm: blk: part: Ad...
288
289
290
291
  		puts ("HOST");
  		break;
  	case IF_TYPE_NVME:
  		puts ("NVMe");
f4d8de48f   Henrik Nordström   sandbox: block dr...
292
  		break;
4ad54ec4d   Tuomas Tynkkynen   blk: Introduce IF...
293
294
295
  	case IF_TYPE_VIRTIO:
  		puts("VirtIO");
  		break;
726c0f1e5   Detlev Zundel   cosmetic: Adjust ...
296
297
298
  	default:
  		puts ("UNKNOWN");
  		break;
affae2bff   wdenk   Initial revision
299
300
301
302
  	}
  	printf (" device %d  --   Partition Type: %s
  
  ",
bcce53d04   Simon Glass   dm: block: Rename...
303
  			dev_desc->devnum, type);
0c9c8fb5e   Gabe Black   disk: Make the di...
304
  #endif /* any CONFIG_..._PARTITION */
96e5b03c8   Simon Glass   dm: part: Convert...
305
  }
0c9c8fb5e   Gabe Black   disk: Make the di...
306

3e8bd4695   Simon Glass   dm: part: Rename ...
307
  void part_print(struct blk_desc *dev_desc)
affae2bff   wdenk   Initial revision
308
  {
96e5b03c8   Simon Glass   dm: part: Convert...
309
  	struct part_driver *drv;
affae2bff   wdenk   Initial revision
310

d47292691   Kever Yang   disk: part: scan ...
311
  	drv = part_driver_lookup_type(dev_desc);
96e5b03c8   Simon Glass   dm: part: Convert...
312
313
314
315
  	if (!drv) {
  		printf("## Unknown partition table type %x
  ",
  		       dev_desc->part_type);
affae2bff   wdenk   Initial revision
316
  		return;
affae2bff   wdenk   Initial revision
317
  	}
96e5b03c8   Simon Glass   dm: part: Convert...
318
319
320
321
322
323
  
  	PRINTF("## Testing for valid %s partition ##
  ", drv->name);
  	print_part_header(drv->name, dev_desc);
  	if (drv->print)
  		drv->print(dev_desc);
affae2bff   wdenk   Initial revision
324
  }
1811a928c   Adam Ford   Move most CONFIG_...
325
  #endif /* CONFIG_HAVE_BLOCK_DEVICE */
2f5016462   Stephen Warren   disk: make get_pa...
326

3e8bd4695   Simon Glass   dm: part: Rename ...
327
  int part_get_info(struct blk_desc *dev_desc, int part,
3f9eb6e10   Pavel Machek   whitespace cleanups
328
  		       disk_partition_t *info)
2f5016462   Stephen Warren   disk: make get_pa...
329
  {
1811a928c   Adam Ford   Move most CONFIG_...
330
  #ifdef CONFIG_HAVE_BLOCK_DEVICE
96e5b03c8   Simon Glass   dm: part: Convert...
331
  	struct part_driver *drv;
2f5016462   Stephen Warren   disk: make get_pa...
332

b331cd620   Patrick Delaunay   cmd, disk: conver...
333
  #if CONFIG_IS_ENABLED(PARTITION_UUIDS)
894bfbbfb   Stephen Warren   disk: part_efi: p...
334
335
336
  	/* The common case is no UUID support */
  	info->uuid[0] = 0;
  #endif
7561b258a   Patrick Delaunay   gpt: add optional...
337
338
339
  #ifdef CONFIG_PARTITION_TYPE_GUID
  	info->type_guid[0] = 0;
  #endif
894bfbbfb   Stephen Warren   disk: part_efi: p...
340

d47292691   Kever Yang   disk: part: scan ...
341
  	drv = part_driver_lookup_type(dev_desc);
96e5b03c8   Simon Glass   dm: part: Convert...
342
343
344
345
346
347
348
  	if (!drv) {
  		debug("## Unknown partition table type %x
  ",
  		      dev_desc->part_type);
  		return -EPROTONOSUPPORT;
  	}
  	if (!drv->get_info) {
2ae67aec5   Nishanth Menon   dm: part: fix mis...
349
350
351
  		PRINTF("## Driver %s does not have the get_info() method
  ",
  		       drv->name);
96e5b03c8   Simon Glass   dm: part: Convert...
352
353
354
355
356
357
  		return -ENOSYS;
  	}
  	if (drv->get_info(dev_desc, part, info) == 0) {
  		PRINTF("## Valid %s partition found ##
  ", drv->name);
  		return 0;
2f5016462   Stephen Warren   disk: make get_pa...
358
  	}
1811a928c   Adam Ford   Move most CONFIG_...
359
  #endif /* CONFIG_HAVE_BLOCK_DEVICE */
2f5016462   Stephen Warren   disk: make get_pa...
360
361
362
  
  	return -1;
  }
99d2c205d   Rob Herring   disk/part: introd...
363

4bbcc965f   Rob Clark   fs: add fs_readdir()
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
  int part_get_info_whole_disk(struct blk_desc *dev_desc, disk_partition_t *info)
  {
  	info->start = 0;
  	info->size = dev_desc->lba;
  	info->blksz = dev_desc->blksz;
  	info->bootable = 0;
  	strcpy((char *)info->type, BOOT_PART_TYPE);
  	strcpy((char *)info->name, "Whole Disk");
  #if CONFIG_IS_ENABLED(PARTITION_UUIDS)
  	info->uuid[0] = 0;
  #endif
  #ifdef CONFIG_PARTITION_TYPE_GUID
  	info->type_guid[0] = 0;
  #endif
  
  	return 0;
  }
ebac37cfb   Simon Glass   dm: blk: Rename g...
381
382
  int blk_get_device_by_str(const char *ifname, const char *dev_hwpart_str,
  			  struct blk_desc **dev_desc)
2023e6086   Stephen Warren   disk: introduce g...
383
384
  {
  	char *ep;
336b6f904   Stephen Warren   disk: support dev...
385
386
387
388
389
390
391
392
393
394
395
396
  	char *dup_str = NULL;
  	const char *dev_str, *hwpart_str;
  	int dev, hwpart;
  
  	hwpart_str = strchr(dev_hwpart_str, '.');
  	if (hwpart_str) {
  		dup_str = strdup(dev_hwpart_str);
  		dup_str[hwpart_str - dev_hwpart_str] = 0;
  		dev_str = dup_str;
  		hwpart_str++;
  	} else {
  		dev_str = dev_hwpart_str;
ecdd57e27   Stephen Warren   disk: default to ...
397
  		hwpart = 0;
336b6f904   Stephen Warren   disk: support dev...
398
  	}
2023e6086   Stephen Warren   disk: introduce g...
399
400
401
402
403
404
  
  	dev = simple_strtoul(dev_str, &ep, 16);
  	if (*ep) {
  		printf("** Bad device specification %s %s **
  ",
  		       ifname, dev_str);
1598dfcb1   Simon Glass   dm: blk: Use the ...
405
  		dev = -EINVAL;
336b6f904   Stephen Warren   disk: support dev...
406
407
408
409
410
411
412
413
414
  		goto cleanup;
  	}
  
  	if (hwpart_str) {
  		hwpart = simple_strtoul(hwpart_str, &ep, 16);
  		if (*ep) {
  			printf("** Bad HW partition specification %s %s **
  ",
  			    ifname, hwpart_str);
1598dfcb1   Simon Glass   dm: blk: Use the ...
415
  			dev = -EINVAL;
336b6f904   Stephen Warren   disk: support dev...
416
417
  			goto cleanup;
  		}
2023e6086   Stephen Warren   disk: introduce g...
418
  	}
336b6f904   Stephen Warren   disk: support dev...
419
  	*dev_desc = get_dev_hwpart(ifname, dev, hwpart);
2023e6086   Stephen Warren   disk: introduce g...
420
  	if (!(*dev_desc) || ((*dev_desc)->type == DEV_TYPE_UNKNOWN)) {
8f690848b   Sam Protsenko   disk: part: Don't...
421
422
  		debug("** Bad device %s %s **
  ", ifname, dev_hwpart_str);
1598dfcb1   Simon Glass   dm: blk: Use the ...
423
  		dev = -ENOENT;
336b6f904   Stephen Warren   disk: support dev...
424
  		goto cleanup;
2023e6086   Stephen Warren   disk: introduce g...
425
  	}
1811a928c   Adam Ford   Move most CONFIG_...
426
  #ifdef CONFIG_HAVE_BLOCK_DEVICE
99e7fc8a2   Erik Tideman   mmc: emmc and hw ...
427
428
429
430
431
432
  	/*
  	 * Updates the partition table for the specified hw partition.
  	 * Does not need to be done for hwpart 0 since it is default and
  	 * already loaded.
  	 */
  	if(hwpart != 0)
3e8bd4695   Simon Glass   dm: part: Rename ...
433
  		part_init(*dev_desc);
99e7fc8a2   Erik Tideman   mmc: emmc and hw ...
434
  #endif
336b6f904   Stephen Warren   disk: support dev...
435
436
  cleanup:
  	free(dup_str);
2023e6086   Stephen Warren   disk: introduce g...
437
438
  	return dev;
  }
10a37fd7a   Stephen Warren   disk: get_device_...
439
440
  #define PART_UNSPECIFIED -2
  #define PART_AUTO -1
e35929e4a   Simon Glass   dm: blk: Rename g...
441
  int blk_get_device_part_str(const char *ifname, const char *dev_part_str,
4101f6879   Simon Glass   dm: Drop the bloc...
442
  			     struct blk_desc **dev_desc,
10a37fd7a   Stephen Warren   disk: get_device_...
443
  			     disk_partition_t *info, int allow_whole_dev)
99d2c205d   Rob Herring   disk/part: introd...
444
  {
10a37fd7a   Stephen Warren   disk: get_device_...
445
446
447
448
  	int ret = -1;
  	const char *part_str;
  	char *dup_str = NULL;
  	const char *dev_str;
99d2c205d   Rob Herring   disk/part: introd...
449
  	int dev;
10a37fd7a   Stephen Warren   disk: get_device_...
450
451
452
453
  	char *ep;
  	int p;
  	int part;
  	disk_partition_t tmpinfo;
afc1744ec   Hans de Goede   disk/part: Only b...
454
  #ifdef CONFIG_SANDBOX
4d907025d   Stephen Warren   sandbox: restore ...
455
  	/*
3f9eb6e10   Pavel Machek   whitespace cleanups
456
  	 * Special-case a pseudo block device "hostfs", to allow access to the
4d907025d   Stephen Warren   sandbox: restore ...
457
458
459
460
461
462
463
464
465
466
  	 * host's own filesystem.
  	 */
  	if (0 == strcmp(ifname, "hostfs")) {
  		*dev_desc = NULL;
  		info->start = 0;
  		info->size = 0;
  		info->blksz = 0;
  		info->bootable = 0;
  		strcpy((char *)info->type, BOOT_PART_TYPE);
  		strcpy((char *)info->name, "Sandbox host");
b331cd620   Patrick Delaunay   cmd, disk: conver...
467
  #if CONFIG_IS_ENABLED(PARTITION_UUIDS)
4d907025d   Stephen Warren   sandbox: restore ...
468
469
  		info->uuid[0] = 0;
  #endif
7561b258a   Patrick Delaunay   gpt: add optional...
470
471
472
  #ifdef CONFIG_PARTITION_TYPE_GUID
  		info->type_guid[0] = 0;
  #endif
4d907025d   Stephen Warren   sandbox: restore ...
473
474
475
  
  		return 0;
  	}
afc1744ec   Hans de Goede   disk/part: Only b...
476
  #endif
4d907025d   Stephen Warren   sandbox: restore ...
477

251cee0db   Hans de Goede   ubifs: Add generi...
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
  #ifdef CONFIG_CMD_UBIFS
  	/*
  	 * Special-case ubi, ubi goes through a mtd, rathen then through
  	 * a regular block device.
  	 */
  	if (0 == strcmp(ifname, "ubi")) {
  		if (!ubifs_is_mounted()) {
  			printf("UBIFS not mounted, use ubifsmount to mount volume first!
  ");
  			return -1;
  		}
  
  		*dev_desc = NULL;
  		memset(info, 0, sizeof(*info));
  		strcpy((char *)info->type, BOOT_PART_TYPE);
  		strcpy((char *)info->name, "UBI");
b331cd620   Patrick Delaunay   cmd, disk: conver...
494
  #if CONFIG_IS_ENABLED(PARTITION_UUIDS)
251cee0db   Hans de Goede   ubifs: Add generi...
495
496
497
498
499
  		info->uuid[0] = 0;
  #endif
  		return 0;
  	}
  #endif
10a37fd7a   Stephen Warren   disk: get_device_...
500
  	/* If no dev_part_str, use bootdevice environment variable */
a10973e7f   Stephen Warren   disk: allow - or ...
501
502
  	if (!dev_part_str || !strlen(dev_part_str) ||
  	    !strcmp(dev_part_str, "-"))
00caae6d4   Simon Glass   env: Rename geten...
503
  		dev_part_str = env_get("bootdevice");
10a37fd7a   Stephen Warren   disk: get_device_...
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
  
  	/* 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...
521
  	}
10a37fd7a   Stephen Warren   disk: get_device_...
522
  	/* Look up the device */
ebac37cfb   Simon Glass   dm: blk: Rename g...
523
  	dev = blk_get_device_by_str(ifname, dev_str, dev_desc);
10a37fd7a   Stephen Warren   disk: get_device_...
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
  	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...
559

10a37fd7a   Stephen Warren   disk: get_device_...
560
561
562
563
564
565
566
567
568
569
  		/*
  		 * 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...
570
  		}
10a37fd7a   Stephen Warren   disk: get_device_...
571

50ffc3b64   Lan Yixun (dlan)   fs/ext4: fix log2...
572
  		(*dev_desc)->log2blksz = LOG2((*dev_desc)->blksz);
4bbcc965f   Rob Clark   fs: add fs_readdir()
573
  		part_get_info_whole_disk(*dev_desc, info);
99d2c205d   Rob Herring   disk/part: introd...
574

10a37fd7a   Stephen Warren   disk: get_device_...
575
576
  		ret = 0;
  		goto cleanup;
99d2c205d   Rob Herring   disk/part: introd...
577
  	}
10a37fd7a   Stephen Warren   disk: get_device_...
578
579
580
581
582
583
584
585
586
587
588
589
  	/*
  	 * 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) {
3e8bd4695   Simon Glass   dm: part: Rename ...
590
  		ret = part_get_info(*dev_desc, part, info);
10a37fd7a   Stephen Warren   disk: get_device_...
591
592
593
594
595
596
597
598
599
600
601
602
  		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++) {
3e8bd4695   Simon Glass   dm: part: Rename ...
603
  			ret = part_get_info(*dev_desc, p, info);
10a37fd7a   Stephen Warren   disk: get_device_...
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
  			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_...
634
635
636
  		} else {
  			printf("** No valid partitions found **
  ");
71bba424a   Stephen Warren   disk: get_device_...
637
  			ret = -1;
10a37fd7a   Stephen Warren   disk: get_device_...
638
639
  			goto cleanup;
  		}
99d2c205d   Rob Herring   disk/part: introd...
640
641
642
643
644
645
  	}
  	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_...
646
647
  		ret  = -1;
  		goto cleanup;
99d2c205d   Rob Herring   disk/part: introd...
648
  	}
50ffc3b64   Lan Yixun (dlan)   fs/ext4: fix log2...
649
  	(*dev_desc)->log2blksz = LOG2((*dev_desc)->blksz);
10a37fd7a   Stephen Warren   disk: get_device_...
650
651
  	ret = part;
  	goto cleanup;
99d2c205d   Rob Herring   disk/part: introd...
652

10a37fd7a   Stephen Warren   disk: get_device_...
653
654
655
  cleanup:
  	free(dup_str);
  	return ret;
99d2c205d   Rob Herring   disk/part: introd...
656
  }
87b8530fe   Petr Kulhavy   disk: part: imple...
657

307890955   Sam Protsenko   disk: Provide API...
658
659
  int part_get_info_by_name_type(struct blk_desc *dev_desc, const char *name,
  			       disk_partition_t *info, int part_type)
87b8530fe   Petr Kulhavy   disk: part: imple...
660
  {
87b8530fe   Petr Kulhavy   disk: part: imple...
661
  	struct part_driver *part_drv;
56670d6fb   Kever Yang   disk: part: use c...
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
  	int ret;
  	int i;
  
  	part_drv = part_driver_lookup_type(dev_desc);
  	if (!part_drv)
  		return -1;
  	for (i = 1; i < part_drv->max_entries; i++) {
  		ret = part_drv->get_info(dev_desc, i, info);
  		if (ret != 0) {
  			/* no more entries in table */
  			break;
  		}
  		if (strcmp(name, (const char *)info->name) == 0) {
  			/* matched */
  			return i;
87b8530fe   Petr Kulhavy   disk: part: imple...
677
678
  		}
  	}
56670d6fb   Kever Yang   disk: part: use c...
679

87b8530fe   Petr Kulhavy   disk: part: imple...
680
681
  	return -1;
  }
da2ee24d9   Petr Kulhavy   disk: part: refac...
682

307890955   Sam Protsenko   disk: Provide API...
683
684
685
686
687
  int part_get_info_by_name(struct blk_desc *dev_desc, const char *name,
  			  disk_partition_t *info)
  {
  	return part_get_info_by_name_type(dev_desc, name, info, PART_TYPE_ALL);
  }
da2ee24d9   Petr Kulhavy   disk: part: refac...
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
  void part_set_generic_name(const struct blk_desc *dev_desc,
  	int part_num, char *name)
  {
  	char *devtype;
  
  	switch (dev_desc->if_type) {
  	case IF_TYPE_IDE:
  	case IF_TYPE_SATA:
  	case IF_TYPE_ATAPI:
  		devtype = "hd";
  		break;
  	case IF_TYPE_SCSI:
  		devtype = "sd";
  		break;
  	case IF_TYPE_USB:
  		devtype = "usbd";
  		break;
  	case IF_TYPE_DOC:
  		devtype = "docd";
  		break;
  	case IF_TYPE_MMC:
  	case IF_TYPE_SD:
  		devtype = "mmcsd";
  		break;
  	default:
  		devtype = "xx";
  		break;
  	}
  
  	sprintf(name, "%s%c%d", devtype, 'a' + dev_desc->devnum, part_num);
  }