
This driver works by wrapping the old SATA API to new blockctrl API
Signed-off-by: Pavel Herrmann morpheus.ibis@gmail.com --- drivers/blockctrl/Makefile | 1 + drivers/blockctrl/sata_legacy.c | 166 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 167 insertions(+) create mode 100644 drivers/blockctrl/sata_legacy.c
diff --git a/drivers/blockctrl/Makefile b/drivers/blockctrl/Makefile index 21a9094..5df1ce1 100644 --- a/drivers/blockctrl/Makefile +++ b/drivers/blockctrl/Makefile @@ -22,6 +22,7 @@ include $(TOPDIR)/config.mk LIB := $(obj)libblockctrl.o
COBJS-${CONFIG_DM_BLOCK} := core.o +COBJS-${CONFIG_BLOCK_SATA_LEGACY} += sata_legacy.o
COBJS := $(COBJS-y) SRCS := $(COBJS:.o=.c) diff --git a/drivers/blockctrl/sata_legacy.c b/drivers/blockctrl/sata_legacy.c new file mode 100644 index 0000000..9cc41a2 --- /dev/null +++ b/drivers/blockctrl/sata_legacy.c @@ -0,0 +1,166 @@ +/* + * (C) Copyright 2012 + * Pavel Herrmann morpheus.ibis@gmail.com + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <dm/blockctrl.h> +#include <dm/structures.h> +#include <dm/manager.h> +#include <sata.h> + +block_dev_desc_t sata_dev_desc[CONFIG_SYS_SATA_MAX_DEVICE]; + +static lbaint_t read(struct instance *i, int port, lbaint_t start, + lbaint_t length, void *buffer) +{ + return sata_read(port, start, length, buffer); +} + +static lbaint_t write(struct instance *i, int port, lbaint_t start, + lbaint_t length, void *buffer) +{ + return sata_write(port, start, length, buffer); +} + +static int scan(struct instance *i, int port) +{ + int error; + + error = scan_sata(port); + if (error) + return error; + + if (!sata_dev_desc[port].lba) + return -ENOENT; + + return 0; +} + +static int get_port_count(struct instance *i) +{ + return CONFIG_SYS_SATA_MAX_DEVICE; +} + +static int get_port_option(struct instance *i, int port, + enum blockctrl_port_option_code op, struct option *result) +{ + switch (op) { + case BLKP_OPT_IFTYPE: + result->flags = OPTION_TYPE_U; + result->data.data_u = BLKP_IFTYPE_SATA; + return 0; + case BLKP_OPT_IFSPEED: + result->flags = OPTION_TYPE_U; + result->data.data_u = 150; + return 0; + case BLKP_OPT_BLOCKSIZE: + result->flags = OPTION_TYPE_U; + result->data.data_u = sata_dev_desc[port].blksz; + return 0; + case BLKP_OPT_BLOCKCOUNT: + result->flags = OPTION_TYPE_U; + result->data.data_u = sata_dev_desc[port].lba; + return 0; + case BLKP_OPT_REMOVABLE: + result->flags = OPTION_TYPE_U; + result->data.data_u = sata_dev_desc[port].removable; + return 0; + case BLKP_OPT_LBA48: +#ifdef CONFIG_LBA48 + result->flags = OPTION_TYPE_U; + result->data.data_u = sata_dev_desc[port].lba48; + return 0; +#else + return -EINVAL; +#endif + case BLKP_OPT_VENDOR: + result->flags = OPTION_TYPE_S; + result->data.data_s = sata_dev_desc[port].vendor; + return 0; + case BLKP_OPT_PRODUCT: + result->flags = OPTION_TYPE_S; + result->data.data_s = sata_dev_desc[port].product; + return 0; + case BLKP_OPT_REVISION: + result->flags = OPTION_TYPE_S; + result->data.data_s = sata_dev_desc[port].revision; + return 0; + } + return -EINVAL; +} + +static struct blockctrl_ops ops = { + .read = read, + .write = write, + .scan = scan, + .get_port_count = get_port_count, + .get_port_option = get_port_option, +}; + +static int sata_init(void) +{ + int rc; + int i; + + for (i = 0; i < CONFIG_SYS_SATA_MAX_DEVICE; i++) { + memset(&sata_dev_desc[i], 0, sizeof(struct block_dev_desc)); + sata_dev_desc[i].if_type = IF_TYPE_SATA; + sata_dev_desc[i].dev = 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].block_read = sata_read; + sata_dev_desc[i].block_write = sata_write; + + rc = init_sata(i); + if (!rc) + rc = scan_sata(i); + } + return rc; +} + +static int bind(struct instance *dev) +{ + return core_bind(CORE_BLOCKCTRL, dev, &ops, NULL); +} + +static int probe(struct instance *dev) +{ + return sata_init(); +} + +static int reloc(struct instance *dev, struct instance *old) +{ + return core_replace(CORE_BLOCKCTRL, dev, old); +} + +static int remove(struct instance *dev) +{ + return 0; +} + +static int unbind(struct instance *dev) +{ + return core_unbind(CORE_BLOCKDEV, dev); +} + +U_BOOT_DRIVER(sata_legacy, bind, probe, reloc, remove, unbind);