diff options
| author | Dave Liu <r63238@freescale.com> | 2008-03-26 22:49:44 +0800 | 
|---|---|---|
| committer | Wolfgang Denk <wd@denx.de> | 2008-03-26 23:38:51 +0100 | 
| commit | c7057b529c3c3cb9c0ac9060686a4068f1491bbe (patch) | |
| tree | 8525c3cd0fabf30fe590d91cfb1902519191993b | |
| parent | 83c7f470a4ce94f33600f11ae85ce4dcf00aa90c (diff) | |
| download | olio-uboot-2014.01-c7057b529c3c3cb9c0ac9060686a4068f1491bbe.tar.xz olio-uboot-2014.01-c7057b529c3c3cb9c0ac9060686a4068f1491bbe.zip | |
ata: add the support for SATA framework
- add the SATA framework
- add the SATA command line
Signed-off-by: Dave Liu <daveliu@freescale.com>
| -rw-r--r-- | common/Makefile | 1 | ||||
| -rw-r--r-- | common/cmd_sata.c | 193 | ||||
| -rw-r--r-- | disk/part.c | 14 | ||||
| -rw-r--r-- | disk/part_dos.c | 2 | ||||
| -rw-r--r-- | disk/part_iso.c | 2 | ||||
| -rw-r--r-- | disk/part_mac.c | 1 | ||||
| -rw-r--r-- | include/part.h | 3 | ||||
| -rw-r--r-- | include/sata.h | 6 | 
8 files changed, 222 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"); diff --git a/disk/part.c b/disk/part.c index 56b9427c2..3c71208a1 100644 --- a/disk/part.c +++ b/disk/part.c @@ -35,6 +35,7 @@  #endif  #if (defined(CONFIG_CMD_IDE) || \ +     defined(CONFIG_CMD_SATA) || \       defined(CONFIG_CMD_SCSI) || \       defined(CONFIG_CMD_USB) || \       defined(CONFIG_MMC) || \ @@ -49,6 +50,9 @@ static const struct block_drvr block_drvr[] = {  #if defined(CONFIG_CMD_IDE)  	{ .name = "ide", .get_dev = ide_get_dev, },  #endif +#if defined(CONFIG_CMD_SATA) +	{.name = "sata", .get_dev = sata_get_dev, }, +#endif  #if defined(CONFIG_CMD_SCSI)  	{ .name = "scsi", .get_dev = scsi_get_dev, },  #endif @@ -87,6 +91,7 @@ block_dev_desc_t *get_dev(char* ifname, int dev)  #endif  #if (defined(CONFIG_CMD_IDE) || \ +     defined(CONFIG_CMD_SATA) || \       defined(CONFIG_CMD_SCSI) || \       defined(CONFIG_CMD_USB) || \       defined(CONFIG_MMC) || \ @@ -116,6 +121,12 @@ void dev_print (block_dev_desc_t *dev_desc)  			dev_desc->vendor,  			dev_desc->revision,  			dev_desc->product); +	} +	if (dev_desc->if_type==IF_TYPE_SATA) { +		printf ("Model: %s Firm: %s Ser#: %s\n", +			dev_desc->vendor, +			dev_desc->revision, +			dev_desc->product);  	} else {  		printf ("Vendor: %s Prod.: %s Rev: %s\n",  			dev_desc->vendor, @@ -177,6 +188,7 @@ void dev_print (block_dev_desc_t *dev_desc)  #endif  #if (defined(CONFIG_CMD_IDE) || \ +     defined(CONFIG_CMD_SATA) || \       defined(CONFIG_CMD_SCSI) || \       defined(CONFIG_CMD_USB) || \       defined(CONFIG_MMC)		|| \ @@ -271,6 +283,8 @@ static void print_part_header (const char *type, block_dev_desc_t * dev_desc)  	switch (dev_desc->if_type) {  		case IF_TYPE_IDE:  	puts ("IDE");  					break; +		case IF_TYPE_SATA:	puts ("SATA"); +					break;  		case IF_TYPE_SCSI: 	puts ("SCSI");  					break;  		case IF_TYPE_ATAPI:	puts ("ATAPI"); diff --git a/disk/part_dos.c b/disk/part_dos.c index 4707f803d..4d778ec5b 100644 --- a/disk/part_dos.c +++ b/disk/part_dos.c @@ -36,6 +36,7 @@  #include "part_dos.h"  #if (defined(CONFIG_CMD_IDE) || \ +     defined(CONFIG_CMD_SATA) || \       defined(CONFIG_CMD_SCSI) || \       defined(CONFIG_CMD_USB) || \       defined(CONFIG_MMC) || \ @@ -194,6 +195,7 @@ static int get_partition_info_extended (block_dev_desc_t *dev_desc, int ext_part  			info->size  = le32_to_int (pt->size4);  			switch(dev_desc->if_type) {  				case IF_TYPE_IDE: +				case IF_TYPE_SATA:  				case IF_TYPE_ATAPI:  					sprintf ((char *)info->name, "hd%c%d\n", 'a' + dev_desc->dev, part_num);  					break; diff --git a/disk/part_iso.c b/disk/part_iso.c index 06dd75eff..489463079 100644 --- a/disk/part_iso.c +++ b/disk/part_iso.c @@ -27,6 +27,7 @@  #if (defined(CONFIG_CMD_IDE) || \       defined(CONFIG_CMD_SCSI) || \ +     defined(CONFIG_CMD_SATA) || \       defined(CONFIG_CMD_USB) || \       defined(CONFIG_MMC) || \       defined(CONFIG_SYSTEMACE) ) && defined(CONFIG_ISO_PARTITION) @@ -157,6 +158,7 @@ int get_partition_info_iso_verb(block_dev_desc_t * dev_desc, int part_num, disk_  	sprintf ((char *)info->type, "U-Boot");  	switch(dev_desc->if_type) {  		case IF_TYPE_IDE: +		case IF_TYPE_SATA:  		case IF_TYPE_ATAPI:  			sprintf ((char *)info->name, "hd%c%d\n", 'a' + dev_desc->dev, part_num);  			break; diff --git a/disk/part_mac.c b/disk/part_mac.c index d303a73f2..1922fe53a 100644 --- a/disk/part_mac.c +++ b/disk/part_mac.c @@ -36,6 +36,7 @@  #if (defined(CONFIG_CMD_IDE) || \       defined(CONFIG_CMD_SCSI) || \ +     defined(CONFIG_CMD_SATA) || \       defined(CONFIG_CMD_USB) || \       defined(CONFIG_MMC) || \       defined(CONFIG_SYSTEMACE) ) && defined(CONFIG_MAC_PARTITION) diff --git a/include/part.h b/include/part.h index 8407aa05d..cb1b75833 100644 --- a/include/part.h +++ b/include/part.h @@ -49,6 +49,7 @@ typedef struct block_dev_desc {  				       unsigned long start,  				       lbaint_t blkcnt,  				       const void *buffer); +	void		*priv;		/* driver private struct pointer */  }block_dev_desc_t;  /* Interface types: */ @@ -60,6 +61,7 @@ typedef struct block_dev_desc {  #define IF_TYPE_DOC		5  #define IF_TYPE_MMC		6  #define IF_TYPE_SD		7 +#define IF_TYPE_SATA		8  /* Part types */  #define PART_TYPE_UNKNOWN	0x00 @@ -92,6 +94,7 @@ typedef struct disk_partition {  /* Misc _get_dev functions */  block_dev_desc_t* get_dev(char* ifname, int dev);  block_dev_desc_t* ide_get_dev(int dev); +block_dev_desc_t* sata_get_dev(int dev);  block_dev_desc_t* scsi_get_dev(int dev);  block_dev_desc_t* usb_stor_get_dev(int dev);  block_dev_desc_t* mmc_get_dev(int dev); diff --git a/include/sata.h b/include/sata.h new file mode 100644 index 000000000..b4b702903 --- /dev/null +++ b/include/sata.h @@ -0,0 +1,6 @@ +int init_sata(int dev); +int scan_sata(int dev); +ulong sata_read(int dev, ulong blknr, ulong blkcnt, void *buffer); +ulong sata_write(int dev, ulong blknr, ulong blkcnt, const void *buffer); + +int sata_initialize(void); |