+// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2000-2005, DENX Software Engineering
* Copyright (C) 2008 Freescale Semiconductor, Inc.
- *
- * SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
+#include <ahci.h>
+#include <blk.h>
#include <dm.h>
+#include <part.h>
#include <sata.h>
+#include <dm/device-internal.h>
+#include <dm/uclass-internal.h>
-struct blk_desc sata_dev_desc[CONFIG_SYS_SATA_MAX_DEVICE];
-
-#ifdef CONFIG_PARTITIONS
-struct blk_desc *sata_get_dev(int dev)
+int sata_reset(struct udevice *dev)
{
- return (dev < CONFIG_SYS_SATA_MAX_DEVICE) ? &sata_dev_desc[dev] : NULL;
-}
-#endif
+ struct ahci_ops *ops = ahci_get_ops(dev);
-#ifdef CONFIG_BLK
-static unsigned long sata_bread(struct udevice *dev, lbaint_t start,
- lbaint_t blkcnt, void *dst)
-{
- return -ENOSYS;
-}
+ if (!ops->reset)
+ return -ENOSYS;
-static unsigned long sata_bwrite(struct udevice *dev, lbaint_t start,
- lbaint_t blkcnt, const void *buffer)
-{
- return -ENOSYS;
+ return ops->reset(dev);
}
-#else
-static unsigned long sata_bread(struct blk_desc *block_dev, lbaint_t start,
- lbaint_t blkcnt, void *dst)
+
+int sata_dm_port_status(struct udevice *dev, int port)
{
- return sata_read(block_dev->devnum, start, blkcnt, dst);
+ struct ahci_ops *ops = ahci_get_ops(dev);
+
+ if (!ops->port_status)
+ return -ENOSYS;
+
+ return ops->port_status(dev, port);
}
-static unsigned long sata_bwrite(struct blk_desc *block_dev, lbaint_t start,
- lbaint_t blkcnt, const void *buffer)
+int sata_scan(struct udevice *dev)
{
- return sata_write(block_dev->devnum, start, blkcnt, buffer);
+ struct ahci_ops *ops = ahci_get_ops(dev);
+
+ if (!ops->scan)
+ return -ENOSYS;
+
+ return ops->scan(dev);
}
-#endif
-int __sata_initialize(void)
+int sata_rescan(bool verbose)
{
- int rc, ret = -1;
- int i;
-
- for (i = 0; i < CONFIG_SYS_SATA_MAX_DEVICE; i++) {
- memset(&sata_dev_desc[i], 0, sizeof(struct blk_desc));
- sata_dev_desc[i].if_type = IF_TYPE_SATA;
- sata_dev_desc[i].devnum = i;
- sata_dev_desc[i].part_type = PART_TYPE_UNKNOWN;
- sata_dev_desc[i].type = DEV_TYPE_HARDDISK;
- sata_dev_desc[i].lba = 0;
- sata_dev_desc[i].blksz = 512;
- sata_dev_desc[i].log2blksz = LOG2(sata_dev_desc[i].blksz);
-#ifndef CONFIG_BLK
- sata_dev_desc[i].block_read = sata_bread;
- sata_dev_desc[i].block_write = sata_bwrite;
-#endif
- rc = init_sata(i);
- if (!rc) {
- rc = scan_sata(i);
- if (!rc && sata_dev_desc[i].lba > 0 &&
- sata_dev_desc[i].blksz > 0) {
- part_init(&sata_dev_desc[i]);
- ret = i;
- }
- }
+ int ret;
+ struct udevice *dev;
+
+ if (verbose)
+ printf("Removing devices on SATA bus...\n");
+
+ blk_unbind_all(UCLASS_AHCI);
+
+ ret = uclass_find_first_device(UCLASS_AHCI, &dev);
+ if (ret || !dev) {
+ printf("Cannot find SATA device (err=%d)\n", ret);
+ return -ENOENT;
+ }
+
+ ret = device_remove(dev, DM_REMOVE_NORMAL);
+ if (ret) {
+ printf("Cannot remove SATA device '%s' (err=%d)\n", dev->name, ret);
+ return -ENOSYS;
+ }
+
+ if (verbose)
+ printf("Rescanning SATA bus for devices...\n");
+
+ ret = uclass_probe_all(UCLASS_AHCI);
+
+ if (ret == -ENODEV) {
+ if (verbose)
+ printf("No SATA block device found\n");
+ return 0;
}
return ret;
}
-int sata_initialize(void) __attribute__((weak, alias("__sata_initialize")));
-__weak int __sata_stop(void)
+static unsigned long sata_bread(struct udevice *dev, lbaint_t start,
+ lbaint_t blkcnt, void *dst)
{
- int i, err = 0;
-
- for (i = 0; i < CONFIG_SYS_SATA_MAX_DEVICE; i++)
- err |= reset_sata(i);
-
- if (err)
- printf("Could not reset some SATA devices\n");
+ return -ENOSYS;
+}
- return err;
+static unsigned long sata_bwrite(struct udevice *dev, lbaint_t start,
+ lbaint_t blkcnt, const void *buffer)
+{
+ return -ENOSYS;
}
-int sata_stop(void) __attribute__((weak, alias("__sata_stop")));
-#ifdef CONFIG_BLK
static const struct blk_ops sata_blk_ops = {
.read = sata_bread,
.write = sata_bwrite,
.id = UCLASS_BLK,
.ops = &sata_blk_ops,
};
-#else
-U_BOOT_LEGACY_BLK(sata) = {
- .if_typename = "sata",
- .if_type = IF_TYPE_SATA,
- .max_devs = CONFIG_SYS_SATA_MAX_DEVICE,
- .desc = sata_dev_desc,
-};
-#endif