1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright (C) 2000-2005, DENX Software Engineering 4 * Wolfgang Denk <wd@denx.de> 5 * Copyright (C) Procsys. All rights reserved. 6 * Mushtaq Khan <mushtaq_k@procsys.com> 7 * <mushtaqk_921@yahoo.co.in> 8 * Copyright (C) 2008 Freescale Semiconductor, Inc. 9 * Dave Liu <daveliu@freescale.com> 10 */ 11 12 #include <common.h> 13 #include <ahci.h> 14 #include <dm.h> 15 #include <sata.h> 16 17 #ifndef CONFIG_AHCI 18 struct blk_desc sata_dev_desc[CONFIG_SYS_SATA_MAX_DEVICE]; 19 #endif 20 21 int sata_reset(struct udevice *dev) 22 { 23 struct ahci_ops *ops = ahci_get_ops(dev); 24 25 if (!ops->reset) 26 return -ENOSYS; 27 28 return ops->reset(dev); 29 } 30 31 int sata_dm_port_status(struct udevice *dev, int port) 32 { 33 struct ahci_ops *ops = ahci_get_ops(dev); 34 35 if (!ops->port_status) 36 return -ENOSYS; 37 38 return ops->port_status(dev, port); 39 } 40 41 int sata_scan(struct udevice *dev) 42 { 43 struct ahci_ops *ops = ahci_get_ops(dev); 44 45 if (!ops->scan) 46 return -ENOSYS; 47 48 return ops->scan(dev); 49 } 50 51 #ifndef CONFIG_AHCI 52 #ifdef CONFIG_PARTITIONS 53 struct blk_desc *sata_get_dev(int dev) 54 { 55 return (dev < CONFIG_SYS_SATA_MAX_DEVICE) ? &sata_dev_desc[dev] : NULL; 56 } 57 #endif 58 #endif 59 60 #ifdef CONFIG_BLK 61 static unsigned long sata_bread(struct udevice *dev, lbaint_t start, 62 lbaint_t blkcnt, void *dst) 63 { 64 return -ENOSYS; 65 } 66 67 static unsigned long sata_bwrite(struct udevice *dev, lbaint_t start, 68 lbaint_t blkcnt, const void *buffer) 69 { 70 return -ENOSYS; 71 } 72 #else 73 static unsigned long sata_bread(struct blk_desc *block_dev, lbaint_t start, 74 lbaint_t blkcnt, void *dst) 75 { 76 return sata_read(block_dev->devnum, start, blkcnt, dst); 77 } 78 79 static unsigned long sata_bwrite(struct blk_desc *block_dev, lbaint_t start, 80 lbaint_t blkcnt, const void *buffer) 81 { 82 return sata_write(block_dev->devnum, start, blkcnt, buffer); 83 } 84 #endif 85 86 #ifndef CONFIG_AHCI 87 int __sata_initialize(void) 88 { 89 int rc, ret = -1; 90 int i; 91 92 for (i = 0; i < CONFIG_SYS_SATA_MAX_DEVICE; i++) { 93 memset(&sata_dev_desc[i], 0, sizeof(struct blk_desc)); 94 sata_dev_desc[i].if_type = IF_TYPE_SATA; 95 sata_dev_desc[i].devnum = i; 96 sata_dev_desc[i].part_type = PART_TYPE_UNKNOWN; 97 sata_dev_desc[i].type = DEV_TYPE_HARDDISK; 98 sata_dev_desc[i].lba = 0; 99 sata_dev_desc[i].blksz = 512; 100 sata_dev_desc[i].log2blksz = LOG2(sata_dev_desc[i].blksz); 101 #ifndef CONFIG_BLK 102 sata_dev_desc[i].block_read = sata_bread; 103 sata_dev_desc[i].block_write = sata_bwrite; 104 #endif 105 rc = init_sata(i); 106 if (!rc) { 107 rc = scan_sata(i); 108 if (!rc && sata_dev_desc[i].lba > 0 && 109 sata_dev_desc[i].blksz > 0) { 110 part_init(&sata_dev_desc[i]); 111 ret = i; 112 } 113 } 114 } 115 116 return ret; 117 } 118 int sata_initialize(void) __attribute__((weak, alias("__sata_initialize"))); 119 120 __weak int __sata_stop(void) 121 { 122 int i, err = 0; 123 124 for (i = 0; i < CONFIG_SYS_SATA_MAX_DEVICE; i++) 125 err |= reset_sata(i); 126 127 if (err) 128 printf("Could not reset some SATA devices\n"); 129 130 return err; 131 } 132 int sata_stop(void) __attribute__((weak, alias("__sata_stop"))); 133 #endif 134 135 #ifdef CONFIG_BLK 136 static const struct blk_ops sata_blk_ops = { 137 .read = sata_bread, 138 .write = sata_bwrite, 139 }; 140 141 U_BOOT_DRIVER(sata_blk) = { 142 .name = "sata_blk", 143 .id = UCLASS_BLK, 144 .ops = &sata_blk_ops, 145 }; 146 #else 147 U_BOOT_LEGACY_BLK(sata) = { 148 .if_typename = "sata", 149 .if_type = IF_TYPE_SATA, 150 .max_devs = CONFIG_SYS_SATA_MAX_DEVICE, 151 .desc = sata_dev_desc, 152 }; 153 #endif 154