summaryrefslogtreecommitdiff
path: root/drivers/block
diff options
context:
space:
mode:
authorBin Meng <bmeng.cn@gmail.com>2017-09-10 05:12:51 -0700
committerTom Rini <trini@konsulko.com>2017-09-10 12:27:37 -0400
commit68e6f221ed08674374dc397fe52a64817599fce7 (patch)
tree0aba1a5779ed24c9d978c985bbe3fd071abc98fb /drivers/block
parenteb81b1a4d3f996072e08b790018edd750210a8c1 (diff)
block: ide: Fix block read/write with driver model
This converts the IDE driver to driver model so that block read and write are fully functional. Fixes: b7c6baef ("x86: Convert MMC to driver model") Reported-by: Heinrich Schuchardt <xypron.glpk@gmx.de> Signed-off-by: Bin Meng <bmeng.cn@gmail.com> Reviewed-by: Simon Glass <sjg@chromium.org> Tested-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Diffstat (limited to 'drivers/block')
-rw-r--r--drivers/block/blk-uclass.c2
-rw-r--r--drivers/block/ide.c73
2 files changed, 74 insertions, 1 deletions
diff --git a/drivers/block/blk-uclass.c b/drivers/block/blk-uclass.c
index 3aec569d124..3c5a87b60a8 100644
--- a/drivers/block/blk-uclass.c
+++ b/drivers/block/blk-uclass.c
@@ -26,7 +26,7 @@ static const char *if_typename_str[IF_TYPE_COUNT] = {
};
static enum uclass_id if_type_uclass_id[IF_TYPE_COUNT] = {
- [IF_TYPE_IDE] = UCLASS_INVALID,
+ [IF_TYPE_IDE] = UCLASS_IDE,
[IF_TYPE_SCSI] = UCLASS_SCSI,
[IF_TYPE_ATAPI] = UCLASS_INVALID,
[IF_TYPE_USB] = UCLASS_MASS_STORAGE,
diff --git a/drivers/block/ide.c b/drivers/block/ide.c
index ce51153099b..ed3b27e6e75 100644
--- a/drivers/block/ide.c
+++ b/drivers/block/ide.c
@@ -827,12 +827,20 @@ void ide_init(void)
ide_ident(&ide_dev_desc[i]);
dev_print(&ide_dev_desc[i]);
+#ifndef CONFIG_BLK
if ((ide_dev_desc[i].lba > 0) && (ide_dev_desc[i].blksz > 0)) {
/* initialize partition type */
part_init(&ide_dev_desc[i]);
}
+#endif
}
WATCHDOG_RESET();
+
+#ifdef CONFIG_BLK
+ struct udevice *dev;
+
+ uclass_first_device(UCLASS_IDE, &dev);
+#endif
}
/* We only need to swap data if we are running on a big endian cpu. */
@@ -1147,6 +1155,26 @@ int ide_device_present(int dev)
#endif
#ifdef CONFIG_BLK
+static int ide_blk_probe(struct udevice *udev)
+{
+ struct blk_desc *desc = dev_get_uclass_platdata(udev);
+
+ /* fill in device vendor/product/rev strings */
+ strncpy(desc->vendor, ide_dev_desc[desc->devnum].vendor,
+ BLK_VEN_SIZE);
+ desc->vendor[BLK_VEN_SIZE] = '\0';
+ strncpy(desc->product, ide_dev_desc[desc->devnum].product,
+ BLK_PRD_SIZE);
+ desc->product[BLK_PRD_SIZE] = '\0';
+ strncpy(desc->revision, ide_dev_desc[desc->devnum].revision,
+ BLK_REV_SIZE);
+ desc->revision[BLK_REV_SIZE] = '\0';
+
+ part_init(desc);
+
+ return 0;
+}
+
static const struct blk_ops ide_blk_ops = {
.read = ide_read,
.write = ide_write,
@@ -1156,6 +1184,51 @@ U_BOOT_DRIVER(ide_blk) = {
.name = "ide_blk",
.id = UCLASS_BLK,
.ops = &ide_blk_ops,
+ .probe = ide_blk_probe,
+};
+
+static int ide_probe(struct udevice *udev)
+{
+ struct udevice *blk_dev;
+ char name[20];
+ int blksz;
+ lbaint_t size;
+ int i;
+ int ret;
+
+ for (i = 0; i < CONFIG_SYS_IDE_MAXDEVICE; i++) {
+ if (ide_dev_desc[i].type != DEV_TYPE_UNKNOWN) {
+ sprintf(name, "blk#%d", i);
+
+ blksz = ide_dev_desc[i].blksz;
+ size = blksz * ide_dev_desc[i].lba;
+ ret = blk_create_devicef(udev, "ide_blk", name,
+ IF_TYPE_IDE, i,
+ blksz, size, &blk_dev);
+ if (ret)
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+U_BOOT_DRIVER(ide) = {
+ .name = "ide",
+ .id = UCLASS_IDE,
+ .probe = ide_probe,
+};
+
+struct pci_device_id ide_supported[] = {
+ { PCI_DEVICE_CLASS(PCI_CLASS_STORAGE_IDE << 8, 0xffff00) },
+ { }
+};
+
+U_BOOT_PCI_DEVICE(ide, ide_supported);
+
+UCLASS_DRIVER(ide) = {
+ .name = "ide",
+ .id = UCLASS_IDE,
};
#else
U_BOOT_LEGACY_BLK(ide) = {