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