Home | History | Annotate | Download | only in block
      1 // SPDX-License-Identifier: GPL-2.0+
      2 /*
      3  * Copyright (C) 2016 Google, Inc
      4  * Written by Simon Glass <sjg (at) chromium.org>
      5  */
      6 
      7 #include <common.h>
      8 #include <blk.h>
      9 #include <dm.h>
     10 #include <dm/device-internal.h>
     11 #include <dm/lists.h>
     12 #include <dm/uclass-internal.h>
     13 
     14 static const char *if_typename_str[IF_TYPE_COUNT] = {
     15 	[IF_TYPE_IDE]		= "ide",
     16 	[IF_TYPE_SCSI]		= "scsi",
     17 	[IF_TYPE_ATAPI]		= "atapi",
     18 	[IF_TYPE_USB]		= "usb",
     19 	[IF_TYPE_DOC]		= "doc",
     20 	[IF_TYPE_MMC]		= "mmc",
     21 	[IF_TYPE_SD]		= "sd",
     22 	[IF_TYPE_SATA]		= "sata",
     23 	[IF_TYPE_HOST]		= "host",
     24 	[IF_TYPE_NVME]		= "nvme",
     25 	[IF_TYPE_EFI]		= "efi",
     26 };
     27 
     28 static enum uclass_id if_type_uclass_id[IF_TYPE_COUNT] = {
     29 	[IF_TYPE_IDE]		= UCLASS_IDE,
     30 	[IF_TYPE_SCSI]		= UCLASS_SCSI,
     31 	[IF_TYPE_ATAPI]		= UCLASS_INVALID,
     32 	[IF_TYPE_USB]		= UCLASS_MASS_STORAGE,
     33 	[IF_TYPE_DOC]		= UCLASS_INVALID,
     34 	[IF_TYPE_MMC]		= UCLASS_MMC,
     35 	[IF_TYPE_SD]		= UCLASS_INVALID,
     36 	[IF_TYPE_SATA]		= UCLASS_AHCI,
     37 	[IF_TYPE_HOST]		= UCLASS_ROOT,
     38 	[IF_TYPE_NVME]		= UCLASS_NVME,
     39 	[IF_TYPE_EFI]		= UCLASS_EFI,
     40 };
     41 
     42 static enum if_type if_typename_to_iftype(const char *if_typename)
     43 {
     44 	int i;
     45 
     46 	for (i = 0; i < IF_TYPE_COUNT; i++) {
     47 		if (if_typename_str[i] &&
     48 		    !strcmp(if_typename, if_typename_str[i]))
     49 			return i;
     50 	}
     51 
     52 	return IF_TYPE_UNKNOWN;
     53 }
     54 
     55 static enum uclass_id if_type_to_uclass_id(enum if_type if_type)
     56 {
     57 	return if_type_uclass_id[if_type];
     58 }
     59 
     60 const char *blk_get_if_type_name(enum if_type if_type)
     61 {
     62 	return if_typename_str[if_type];
     63 }
     64 
     65 struct blk_desc *blk_get_devnum_by_type(enum if_type if_type, int devnum)
     66 {
     67 	struct blk_desc *desc;
     68 	struct udevice *dev;
     69 	int ret;
     70 
     71 	ret = blk_get_device(if_type, devnum, &dev);
     72 	if (ret)
     73 		return NULL;
     74 	desc = dev_get_uclass_platdata(dev);
     75 
     76 	return desc;
     77 }
     78 
     79 /*
     80  * This function is complicated with driver model. We look up the interface
     81  * name in a local table. This gives us an interface type which we can match
     82  * against the uclass of the block device's parent.
     83  */
     84 struct blk_desc *blk_get_devnum_by_typename(const char *if_typename, int devnum)
     85 {
     86 	enum uclass_id uclass_id;
     87 	enum if_type if_type;
     88 	struct udevice *dev;
     89 	struct uclass *uc;
     90 	int ret;
     91 
     92 	if_type = if_typename_to_iftype(if_typename);
     93 	if (if_type == IF_TYPE_UNKNOWN) {
     94 		debug("%s: Unknown interface type '%s'\n", __func__,
     95 		      if_typename);
     96 		return NULL;
     97 	}
     98 	uclass_id = if_type_to_uclass_id(if_type);
     99 	if (uclass_id == UCLASS_INVALID) {
    100 		debug("%s: Unknown uclass for interface type'\n",
    101 		      if_typename_str[if_type]);
    102 		return NULL;
    103 	}
    104 
    105 	ret = uclass_get(UCLASS_BLK, &uc);
    106 	if (ret)
    107 		return NULL;
    108 	uclass_foreach_dev(dev, uc) {
    109 		struct blk_desc *desc = dev_get_uclass_platdata(dev);
    110 
    111 		debug("%s: if_type=%d, devnum=%d: %s, %d, %d\n", __func__,
    112 		      if_type, devnum, dev->name, desc->if_type, desc->devnum);
    113 		if (desc->devnum != devnum)
    114 			continue;
    115 
    116 		/* Find out the parent device uclass */
    117 		if (device_get_uclass_id(dev->parent) != uclass_id) {
    118 			debug("%s: parent uclass %d, this dev %d\n", __func__,
    119 			      device_get_uclass_id(dev->parent), uclass_id);
    120 			continue;
    121 		}
    122 
    123 		if (device_probe(dev))
    124 			return NULL;
    125 
    126 		debug("%s: Device desc %p\n", __func__, desc);
    127 		return desc;
    128 	}
    129 	debug("%s: No device found\n", __func__);
    130 
    131 	return NULL;
    132 }
    133 
    134 /**
    135  * get_desc() - Get the block device descriptor for the given device number
    136  *
    137  * @if_type:	Interface type
    138  * @devnum:	Device number (0 = first)
    139  * @descp:	Returns block device descriptor on success
    140  * @return 0 on success, -ENODEV if there is no such device and no device
    141  * with a higher device number, -ENOENT if there is no such device but there
    142  * is one with a higher number, or other -ve on other error.
    143  */
    144 static int get_desc(enum if_type if_type, int devnum, struct blk_desc **descp)
    145 {
    146 	bool found_more = false;
    147 	struct udevice *dev;
    148 	struct uclass *uc;
    149 	int ret;
    150 
    151 	*descp = NULL;
    152 	ret = uclass_get(UCLASS_BLK, &uc);
    153 	if (ret)
    154 		return ret;
    155 	uclass_foreach_dev(dev, uc) {
    156 		struct blk_desc *desc = dev_get_uclass_platdata(dev);
    157 
    158 		debug("%s: if_type=%d, devnum=%d: %s, %d, %d\n", __func__,
    159 		      if_type, devnum, dev->name, desc->if_type, desc->devnum);
    160 		if (desc->if_type == if_type) {
    161 			if (desc->devnum == devnum) {
    162 				ret = device_probe(dev);
    163 				if (ret)
    164 					return ret;
    165 
    166 				*descp = desc;
    167 				return 0;
    168 			} else if (desc->devnum > devnum) {
    169 				found_more = true;
    170 			}
    171 		}
    172 	}
    173 
    174 	return found_more ? -ENOENT : -ENODEV;
    175 }
    176 
    177 int blk_select_hwpart_devnum(enum if_type if_type, int devnum, int hwpart)
    178 {
    179 	struct udevice *dev;
    180 	int ret;
    181 
    182 	ret = blk_get_device(if_type, devnum, &dev);
    183 	if (ret)
    184 		return ret;
    185 
    186 	return blk_select_hwpart(dev, hwpart);
    187 }
    188 
    189 int blk_list_part(enum if_type if_type)
    190 {
    191 	struct blk_desc *desc;
    192 	int devnum, ok;
    193 	int ret;
    194 
    195 	for (ok = 0, devnum = 0;; ++devnum) {
    196 		ret = get_desc(if_type, devnum, &desc);
    197 		if (ret == -ENODEV)
    198 			break;
    199 		else if (ret)
    200 			continue;
    201 		if (desc->part_type != PART_TYPE_UNKNOWN) {
    202 			++ok;
    203 			if (devnum)
    204 				putc('\n');
    205 			part_print(desc);
    206 		}
    207 	}
    208 	if (!ok)
    209 		return -ENODEV;
    210 
    211 	return 0;
    212 }
    213 
    214 int blk_print_part_devnum(enum if_type if_type, int devnum)
    215 {
    216 	struct blk_desc *desc;
    217 	int ret;
    218 
    219 	ret = get_desc(if_type, devnum, &desc);
    220 	if (ret)
    221 		return ret;
    222 	if (desc->type == DEV_TYPE_UNKNOWN)
    223 		return -ENOENT;
    224 	part_print(desc);
    225 
    226 	return 0;
    227 }
    228 
    229 void blk_list_devices(enum if_type if_type)
    230 {
    231 	struct blk_desc *desc;
    232 	int ret;
    233 	int i;
    234 
    235 	for (i = 0;; ++i) {
    236 		ret = get_desc(if_type, i, &desc);
    237 		if (ret == -ENODEV)
    238 			break;
    239 		else if (ret)
    240 			continue;
    241 		if (desc->type == DEV_TYPE_UNKNOWN)
    242 			continue;  /* list only known devices */
    243 		printf("Device %d: ", i);
    244 		dev_print(desc);
    245 	}
    246 }
    247 
    248 int blk_print_device_num(enum if_type if_type, int devnum)
    249 {
    250 	struct blk_desc *desc;
    251 	int ret;
    252 
    253 	ret = get_desc(if_type, devnum, &desc);
    254 	if (ret)
    255 		return ret;
    256 	printf("\nIDE device %d: ", devnum);
    257 	dev_print(desc);
    258 
    259 	return 0;
    260 }
    261 
    262 int blk_show_device(enum if_type if_type, int devnum)
    263 {
    264 	struct blk_desc *desc;
    265 	int ret;
    266 
    267 	printf("\nDevice %d: ", devnum);
    268 	ret = get_desc(if_type, devnum, &desc);
    269 	if (ret == -ENODEV || ret == -ENOENT) {
    270 		printf("unknown device\n");
    271 		return -ENODEV;
    272 	}
    273 	if (ret)
    274 		return ret;
    275 	dev_print(desc);
    276 
    277 	if (desc->type == DEV_TYPE_UNKNOWN)
    278 		return -ENOENT;
    279 
    280 	return 0;
    281 }
    282 
    283 ulong blk_read_devnum(enum if_type if_type, int devnum, lbaint_t start,
    284 		      lbaint_t blkcnt, void *buffer)
    285 {
    286 	struct blk_desc *desc;
    287 	ulong n;
    288 	int ret;
    289 
    290 	ret = get_desc(if_type, devnum, &desc);
    291 	if (ret)
    292 		return ret;
    293 	n = blk_dread(desc, start, blkcnt, buffer);
    294 	if (IS_ERR_VALUE(n))
    295 		return n;
    296 
    297 	return n;
    298 }
    299 
    300 ulong blk_write_devnum(enum if_type if_type, int devnum, lbaint_t start,
    301 		       lbaint_t blkcnt, const void *buffer)
    302 {
    303 	struct blk_desc *desc;
    304 	int ret;
    305 
    306 	ret = get_desc(if_type, devnum, &desc);
    307 	if (ret)
    308 		return ret;
    309 	return blk_dwrite(desc, start, blkcnt, buffer);
    310 }
    311 
    312 int blk_select_hwpart(struct udevice *dev, int hwpart)
    313 {
    314 	const struct blk_ops *ops = blk_get_ops(dev);
    315 
    316 	if (!ops)
    317 		return -ENOSYS;
    318 	if (!ops->select_hwpart)
    319 		return 0;
    320 
    321 	return ops->select_hwpart(dev, hwpart);
    322 }
    323 
    324 int blk_dselect_hwpart(struct blk_desc *desc, int hwpart)
    325 {
    326 	return blk_select_hwpart(desc->bdev, hwpart);
    327 }
    328 
    329 int blk_first_device(int if_type, struct udevice **devp)
    330 {
    331 	struct blk_desc *desc;
    332 	int ret;
    333 
    334 	ret = uclass_find_first_device(UCLASS_BLK, devp);
    335 	if (ret)
    336 		return ret;
    337 	if (!*devp)
    338 		return -ENODEV;
    339 	do {
    340 		desc = dev_get_uclass_platdata(*devp);
    341 		if (desc->if_type == if_type)
    342 			return 0;
    343 		ret = uclass_find_next_device(devp);
    344 		if (ret)
    345 			return ret;
    346 	} while (*devp);
    347 
    348 	return -ENODEV;
    349 }
    350 
    351 int blk_next_device(struct udevice **devp)
    352 {
    353 	struct blk_desc *desc;
    354 	int ret, if_type;
    355 
    356 	desc = dev_get_uclass_platdata(*devp);
    357 	if_type = desc->if_type;
    358 	do {
    359 		ret = uclass_find_next_device(devp);
    360 		if (ret)
    361 			return ret;
    362 		if (!*devp)
    363 			return -ENODEV;
    364 		desc = dev_get_uclass_platdata(*devp);
    365 		if (desc->if_type == if_type)
    366 			return 0;
    367 	} while (1);
    368 }
    369 
    370 int blk_find_device(int if_type, int devnum, struct udevice **devp)
    371 {
    372 	struct uclass *uc;
    373 	struct udevice *dev;
    374 	int ret;
    375 
    376 	ret = uclass_get(UCLASS_BLK, &uc);
    377 	if (ret)
    378 		return ret;
    379 	uclass_foreach_dev(dev, uc) {
    380 		struct blk_desc *desc = dev_get_uclass_platdata(dev);
    381 
    382 		debug("%s: if_type=%d, devnum=%d: %s, %d, %d\n", __func__,
    383 		      if_type, devnum, dev->name, desc->if_type, desc->devnum);
    384 		if (desc->if_type == if_type && desc->devnum == devnum) {
    385 			*devp = dev;
    386 			return 0;
    387 		}
    388 	}
    389 
    390 	return -ENODEV;
    391 }
    392 
    393 int blk_get_device(int if_type, int devnum, struct udevice **devp)
    394 {
    395 	int ret;
    396 
    397 	ret = blk_find_device(if_type, devnum, devp);
    398 	if (ret)
    399 		return ret;
    400 
    401 	return device_probe(*devp);
    402 }
    403 
    404 unsigned long blk_dread(struct blk_desc *block_dev, lbaint_t start,
    405 			lbaint_t blkcnt, void *buffer)
    406 {
    407 	struct udevice *dev = block_dev->bdev;
    408 	const struct blk_ops *ops = blk_get_ops(dev);
    409 	ulong blks_read;
    410 
    411 	if (!ops->read)
    412 		return -ENOSYS;
    413 
    414 	if (blkcache_read(block_dev->if_type, block_dev->devnum,
    415 			  start, blkcnt, block_dev->blksz, buffer))
    416 		return blkcnt;
    417 	blks_read = ops->read(dev, start, blkcnt, buffer);
    418 	if (blks_read == blkcnt)
    419 		blkcache_fill(block_dev->if_type, block_dev->devnum,
    420 			      start, blkcnt, block_dev->blksz, buffer);
    421 
    422 	return blks_read;
    423 }
    424 
    425 unsigned long blk_dwrite(struct blk_desc *block_dev, lbaint_t start,
    426 			 lbaint_t blkcnt, const void *buffer)
    427 {
    428 	struct udevice *dev = block_dev->bdev;
    429 	const struct blk_ops *ops = blk_get_ops(dev);
    430 
    431 	if (!ops->write)
    432 		return -ENOSYS;
    433 
    434 	blkcache_invalidate(block_dev->if_type, block_dev->devnum);
    435 	return ops->write(dev, start, blkcnt, buffer);
    436 }
    437 
    438 unsigned long blk_derase(struct blk_desc *block_dev, lbaint_t start,
    439 			 lbaint_t blkcnt)
    440 {
    441 	struct udevice *dev = block_dev->bdev;
    442 	const struct blk_ops *ops = blk_get_ops(dev);
    443 
    444 	if (!ops->erase)
    445 		return -ENOSYS;
    446 
    447 	blkcache_invalidate(block_dev->if_type, block_dev->devnum);
    448 	return ops->erase(dev, start, blkcnt);
    449 }
    450 
    451 int blk_prepare_device(struct udevice *dev)
    452 {
    453 	struct blk_desc *desc = dev_get_uclass_platdata(dev);
    454 
    455 	part_init(desc);
    456 
    457 	return 0;
    458 }
    459 
    460 int blk_get_from_parent(struct udevice *parent, struct udevice **devp)
    461 {
    462 	struct udevice *dev;
    463 	enum uclass_id id;
    464 	int ret;
    465 
    466 	device_find_first_child(parent, &dev);
    467 	if (!dev) {
    468 		debug("%s: No block device found for parent '%s'\n", __func__,
    469 		      parent->name);
    470 		return -ENODEV;
    471 	}
    472 	id = device_get_uclass_id(dev);
    473 	if (id != UCLASS_BLK) {
    474 		debug("%s: Incorrect uclass %s for block device '%s'\n",
    475 		      __func__, uclass_get_name(id), dev->name);
    476 		return -ENOTBLK;
    477 	}
    478 	ret = device_probe(dev);
    479 	if (ret)
    480 		return ret;
    481 	*devp = dev;
    482 
    483 	return 0;
    484 }
    485 
    486 int blk_find_max_devnum(enum if_type if_type)
    487 {
    488 	struct udevice *dev;
    489 	int max_devnum = -ENODEV;
    490 	struct uclass *uc;
    491 	int ret;
    492 
    493 	ret = uclass_get(UCLASS_BLK, &uc);
    494 	if (ret)
    495 		return ret;
    496 	uclass_foreach_dev(dev, uc) {
    497 		struct blk_desc *desc = dev_get_uclass_platdata(dev);
    498 
    499 		if (desc->if_type == if_type && desc->devnum > max_devnum)
    500 			max_devnum = desc->devnum;
    501 	}
    502 
    503 	return max_devnum;
    504 }
    505 
    506 static int blk_next_free_devnum(enum if_type if_type)
    507 {
    508 	int ret;
    509 
    510 	ret = blk_find_max_devnum(if_type);
    511 	if (ret == -ENODEV)
    512 		return 0;
    513 	if (ret < 0)
    514 		return ret;
    515 
    516 	return ret + 1;
    517 }
    518 
    519 static int blk_claim_devnum(enum if_type if_type, int devnum)
    520 {
    521 	struct udevice *dev;
    522 	struct uclass *uc;
    523 	int ret;
    524 
    525 	ret = uclass_get(UCLASS_BLK, &uc);
    526 	if (ret)
    527 		return ret;
    528 	uclass_foreach_dev(dev, uc) {
    529 		struct blk_desc *desc = dev_get_uclass_platdata(dev);
    530 
    531 		if (desc->if_type == if_type && desc->devnum == devnum) {
    532 			int next = blk_next_free_devnum(if_type);
    533 
    534 			if (next < 0)
    535 				return next;
    536 			desc->devnum = next;
    537 			return 0;
    538 		}
    539 	}
    540 
    541 	return -ENOENT;
    542 }
    543 
    544 int blk_create_device(struct udevice *parent, const char *drv_name,
    545 		      const char *name, int if_type, int devnum, int blksz,
    546 		      lbaint_t lba, struct udevice **devp)
    547 {
    548 	struct blk_desc *desc;
    549 	struct udevice *dev;
    550 	int ret;
    551 
    552 	if (devnum == -1) {
    553 		devnum = blk_next_free_devnum(if_type);
    554 	} else {
    555 		ret = blk_claim_devnum(if_type, devnum);
    556 		if (ret < 0 && ret != -ENOENT)
    557 			return ret;
    558 	}
    559 	if (devnum < 0)
    560 		return devnum;
    561 	ret = device_bind_driver(parent, drv_name, name, &dev);
    562 	if (ret)
    563 		return ret;
    564 	desc = dev_get_uclass_platdata(dev);
    565 	desc->if_type = if_type;
    566 	desc->blksz = blksz;
    567 	desc->lba = lba;
    568 	desc->part_type = PART_TYPE_UNKNOWN;
    569 	desc->bdev = dev;
    570 	desc->devnum = devnum;
    571 	*devp = dev;
    572 
    573 	return 0;
    574 }
    575 
    576 int blk_create_devicef(struct udevice *parent, const char *drv_name,
    577 		       const char *name, int if_type, int devnum, int blksz,
    578 		       lbaint_t lba, struct udevice **devp)
    579 {
    580 	char dev_name[30], *str;
    581 	int ret;
    582 
    583 	snprintf(dev_name, sizeof(dev_name), "%s.%s", parent->name, name);
    584 	str = strdup(dev_name);
    585 	if (!str)
    586 		return -ENOMEM;
    587 
    588 	ret = blk_create_device(parent, drv_name, str, if_type, devnum,
    589 				blksz, lba, devp);
    590 	if (ret) {
    591 		free(str);
    592 		return ret;
    593 	}
    594 	device_set_name_alloced(*devp);
    595 
    596 	return 0;
    597 }
    598 
    599 int blk_unbind_all(int if_type)
    600 {
    601 	struct uclass *uc;
    602 	struct udevice *dev, *next;
    603 	int ret;
    604 
    605 	ret = uclass_get(UCLASS_BLK, &uc);
    606 	if (ret)
    607 		return ret;
    608 	uclass_foreach_dev_safe(dev, next, uc) {
    609 		struct blk_desc *desc = dev_get_uclass_platdata(dev);
    610 
    611 		if (desc->if_type == if_type) {
    612 			ret = device_remove(dev, DM_REMOVE_NORMAL);
    613 			if (ret)
    614 				return ret;
    615 			ret = device_unbind(dev);
    616 			if (ret)
    617 				return ret;
    618 		}
    619 	}
    620 
    621 	return 0;
    622 }
    623 
    624 UCLASS_DRIVER(blk) = {
    625 	.id		= UCLASS_BLK,
    626 	.name		= "blk",
    627 	.per_device_platdata_auto_alloc_size = sizeof(struct blk_desc),
    628 };
    629