diff options
Diffstat (limited to 'common')
| -rw-r--r-- | common/Makefile | 1 | ||||
| -rw-r--r-- | common/cmd_sata.c | 193 | 
2 files changed, 194 insertions, 0 deletions
| diff --git a/common/Makefile b/common/Makefile index 5c93abb19..35ea3745f 100644 --- a/common/Makefile +++ b/common/Makefile @@ -88,6 +88,7 @@ COBJS-y += cmd_pcmcia.o  COBJS-$(CONFIG_CMD_PORTIO) += cmd_portio.o  COBJS-$(CONFIG_CMD_REGINFO) += cmd_reginfo.o  COBJS-$(CONFIG_CMD_REISER) += cmd_reiser.o +COBJS-$(CONFIG_CMD_SATA) += cmd_sata.o  COBJS-$(CONFIG_CMD_SCSI) += cmd_scsi.o  COBJS-$(CONFIG_CMD_SETEXPR) += cmd_setexpr.o  COBJS-$(CONFIG_CMD_SPI) += cmd_spi.o diff --git a/common/cmd_sata.c b/common/cmd_sata.c new file mode 100644 index 000000000..79c2495d6 --- /dev/null +++ b/common/cmd_sata.c @@ -0,0 +1,193 @@ +/* + * Copyright (C) 2000-2005, DENX Software Engineering + *		Wolfgang Denk <wd@denx.de> + * Copyright (C) Procsys. All rights reserved. + *		Mushtaq Khan <mushtaq_k@procsys.com> + *			<mushtaqk_921@yahoo.co.in> + * Copyright (C) 2008 Freescale Semiconductor, Inc. + *		Dave Liu <daveliu@freescale.com> + * + * 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 <common.h> +#include <command.h> +#include <part.h> +#include <sata.h> + +int curr_device = -1; +block_dev_desc_t sata_dev_desc[CFG_SATA_MAX_DEVICE]; + +int sata_initialize(void) +{ +	int rc; +	int i; + +	for (i = 0; i < CFG_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); +		rc = scan_sata(i); +		if ((sata_dev_desc[i].lba > 0) && (sata_dev_desc[i].blksz > 0)) +			init_part(&sata_dev_desc[i]); +	} +	curr_device = 0; +	return rc; +} + +block_dev_desc_t *sata_get_dev(int dev) +{ +	return (dev < CFG_SATA_MAX_DEVICE) ? &sata_dev_desc[dev] : NULL; +} + +int do_sata(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ +	int rc = 0; + +	switch (argc) { +	case 0: +	case 1: +		printf("Usage:\n%s\n", cmdtp->usage); +		return 1; +	case 2: +		if (strncmp(argv[1],"inf", 3) == 0) { +			int i; +			putc('\n'); +			for (i = 0; i < CFG_SATA_MAX_DEVICE; ++i) { +				if (sata_dev_desc[i].type == DEV_TYPE_UNKNOWN) +					continue; +				printf ("SATA device %d: ", i); +				dev_print(&sata_dev_desc[i]); +			} +			return 0; +		} else if (strncmp(argv[1],"dev", 3) == 0) { +			if ((curr_device < 0) || (curr_device >= CFG_SATA_MAX_DEVICE)) { +				puts("\nno SATA devices available\n"); +				return 1; +			} +			printf("\nSATA device %d: ", curr_device); +			dev_print(&sata_dev_desc[curr_device]); +			return 0; +		} else if (strncmp(argv[1],"part",4) == 0) { +			int dev, ok; + +			for (ok = 0, dev = 0; dev < CFG_SATA_MAX_DEVICE; ++dev) { +				if (sata_dev_desc[dev].part_type != PART_TYPE_UNKNOWN) { +					++ok; +					if (dev) +						putc ('\n'); +					print_part(&sata_dev_desc[dev]); +				} +			} +			if (!ok) { +				puts("\nno SATA devices available\n"); +				rc ++; +			} +			return rc; +		} +		printf("Usage:\n%s\n", cmdtp->usage); +		return 1; +	case 3: +		if (strncmp(argv[1], "dev", 3) == 0) { +			int dev = (int)simple_strtoul(argv[2], NULL, 10); + +			printf("\nSATA device %d: ", dev); +			if (dev >= CFG_SATA_MAX_DEVICE) { +				puts ("unknown device\n"); +				return 1; +			} +			dev_print(&sata_dev_desc[dev]); + +			if (sata_dev_desc[dev].type == DEV_TYPE_UNKNOWN) +				return 1; + +			curr_device = dev; + +			puts("... is now current device\n"); + +			return 0; +		} else if (strncmp(argv[1], "part", 4) == 0) { +			int dev = (int)simple_strtoul(argv[2], NULL, 10); + +			if (sata_dev_desc[dev].part_type != PART_TYPE_UNKNOWN) { +				print_part(&sata_dev_desc[dev]); +			} else { +				printf("\nSATA device %d not available\n", dev); +				rc = 1; +			} +			return rc; +		} +		printf ("Usage:\n%s\n", cmdtp->usage); +		return 1; + +	default: /* at least 4 args */ +		if (strcmp(argv[1], "read") == 0) { +			ulong addr = simple_strtoul(argv[2], NULL, 16); +			ulong cnt = simple_strtoul(argv[4], NULL, 16); +			ulong n; +			lbaint_t blk = simple_strtoul(argv[3], NULL, 16); + +			printf("\nSATA read: device %d block # %ld, count %ld ... ", +				curr_device, blk, cnt); + +			n = sata_read(curr_device, blk, cnt, (u32 *)addr); + +			/* flush cache after read */ +			flush_cache(addr, cnt * sata_dev_desc[curr_device].blksz); + +			printf("%ld blocks read: %s\n", +				n, (n==cnt) ? "OK" : "ERROR"); +			return (n == cnt) ? 0 : 1; +		} else if (strcmp(argv[1], "write") == 0) { +			ulong addr = simple_strtoul(argv[2], NULL, 16); +			ulong cnt = simple_strtoul(argv[4], NULL, 16); +			ulong n; + +			lbaint_t blk = simple_strtoul(argv[3], NULL, 16); + +			printf("\nSATA write: device %d block # %ld, count %ld ... ", +				curr_device, blk, cnt); + +			n = sata_write(curr_device, blk, cnt, (u32 *)addr); + +			printf("%ld blocks written: %s\n", +				n, (n == cnt) ? "OK" : "ERROR"); +			return (n == cnt) ? 0 : 1; +		} else { +			printf("Usage:\n%s\n", cmdtp->usage); +			rc = 1; +		} + +		return rc; +	} +} + +U_BOOT_CMD( +	sata, 5, 1, do_sata, +	"sata	- SATA sub system\n", +	"sata info - show available SATA devices\n" +	"sata device [dev] - show or set current device\n" +	"sata part [dev] - print partition table\n" +	"sata read addr blk# cnt\n" +	"sata write addr blk# cnt\n"); |