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