1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * Software partition device (UCLASS_PARTITION) 4 * 5 * Copyright (c) 2021 Linaro Limited 6 * Author: AKASHI Takahiro 7 */ 8 9#define LOG_CATEGORY UCLASS_PARTITION 10 11#include <common.h> 12#include <blk.h> 13#include <dm.h> 14#include <log.h> 15#include <part.h> 16#include <vsprintf.h> 17#include <dm/device-internal.h> 18#include <dm/lists.h> 19 20/** 21 * disk_blk_part_validate() - Check whether access to partition is within limits 22 * 23 * @dev: Device (partition udevice) 24 * @start: Start block for the access(from start of partition) 25 * @blkcnt: Number of blocks to access (within the partition) 26 * @return 0 on valid block range, or -ve on error. 27 */ 28static int disk_blk_part_validate(struct udevice *dev, lbaint_t start, lbaint_t blkcnt) 29{ 30 struct disk_part *part = dev_get_uclass_plat(dev); 31 32 if (device_get_uclass_id(dev) != UCLASS_PARTITION) 33 return -ENOSYS; 34 35 if (start >= part->gpt_part_info.size) 36 return -E2BIG; 37 38 if ((start + blkcnt) > part->gpt_part_info.size) 39 return -ERANGE; 40 41 return 0; 42} 43 44/** 45 * disk_blk_part_offset() - Compute offset from start of block device 46 * 47 * @dev: Device (partition udevice) 48 * @start: Start block for the access (from start of partition) 49 * @return Start block for the access (from start of block device) 50 */ 51static lbaint_t disk_blk_part_offset(struct udevice *dev, lbaint_t start) 52{ 53 struct disk_part *part = dev_get_uclass_plat(dev); 54 55 return start + part->gpt_part_info.start; 56} 57 58/* 59 * BLOCK IO APIs 60 */ 61/** 62 * disk_blk_read() - Read from a block device partition 63 * 64 * @dev: Device to read from (partition udevice) 65 * @start: Start block for the read (from start of partition) 66 * @blkcnt: Number of blocks to read (within the partition) 67 * @buffer: Place to put the data 68 * @return number of blocks read (which may be less than @blkcnt), 69 * or -ve on error. This never returns 0 unless @blkcnt is 0 70 */ 71unsigned long disk_blk_read(struct udevice *dev, lbaint_t start, 72 lbaint_t blkcnt, void *buffer) 73{ 74 int ret = disk_blk_part_validate(dev, start, blkcnt); 75 76 if (ret) 77 return ret; 78 79 return blk_read(dev_get_parent(dev), disk_blk_part_offset(dev, start), 80 blkcnt, buffer); 81} 82 83/** 84 * disk_blk_write() - Write to a block device 85 * 86 * @dev: Device to write to (partition udevice) 87 * @start: Start block for the write (from start of partition) 88 * @blkcnt: Number of blocks to write (within the partition) 89 * @buffer: Data to write 90 * @return number of blocks written (which may be less than @blkcnt), 91 * or -ve on error. This never returns 0 unless @blkcnt is 0 92 */ 93unsigned long disk_blk_write(struct udevice *dev, lbaint_t start, 94 lbaint_t blkcnt, const void *buffer) 95{ 96 int ret = disk_blk_part_validate(dev, start, blkcnt); 97 98 if (ret) 99 return ret; 100 101 return blk_write(dev_get_parent(dev), disk_blk_part_offset(dev, start), 102 blkcnt, buffer); 103} 104 105/** 106 * disk_blk_erase() - Erase part of a block device 107 * 108 * @dev: Device to erase (partition udevice) 109 * @start: Start block for the erase (from start of partition) 110 * @blkcnt: Number of blocks to erase (within the partition) 111 * @return number of blocks erased (which may be less than @blkcnt), 112 * or -ve on error. This never returns 0 unless @blkcnt is 0 113 */ 114unsigned long disk_blk_erase(struct udevice *dev, lbaint_t start, 115 lbaint_t blkcnt) 116{ 117 int ret = disk_blk_part_validate(dev, start, blkcnt); 118 119 if (ret) 120 return ret; 121 122 return blk_erase(dev_get_parent(dev), disk_blk_part_offset(dev, start), 123 blkcnt); 124} 125 126UCLASS_DRIVER(partition) = { 127 .id = UCLASS_PARTITION, 128 .per_device_plat_auto = sizeof(struct disk_part), 129 .name = "partition", 130}; 131 132static const struct blk_ops blk_part_ops = { 133 .read = disk_blk_read, 134 .write = disk_blk_write, 135 .erase = disk_blk_erase, 136}; 137 138U_BOOT_DRIVER(blk_partition) = { 139 .name = "blk_partition", 140 .id = UCLASS_PARTITION, 141 .ops = &blk_part_ops, 142}; 143