From c7057b529c3c3cb9c0ac9060686a4068f1491bbe Mon Sep 17 00:00:00 2001 From: Dave Liu Date: Wed, 26 Mar 2008 22:49:44 +0800 Subject: ata: add the support for SATA framework - add the SATA framework - add the SATA command line Signed-off-by: Dave Liu --- common/cmd_sata.c | 193 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 193 insertions(+) create mode 100644 common/cmd_sata.c (limited to 'common/cmd_sata.c') diff --git a/common/cmd_sata.c b/common/cmd_sata.c new file mode 100644 index 0000000000..79c2495d66 --- /dev/null +++ b/common/cmd_sata.c @@ -0,0 +1,193 @@ +/* + * Copyright (C) 2000-2005, DENX Software Engineering + * Wolfgang Denk + * Copyright (C) Procsys. All rights reserved. + * Mushtaq Khan + * + * Copyright (C) 2008 Freescale Semiconductor, Inc. + * Dave Liu + * + * 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 +#include +#include +#include + +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"); -- cgit v1.2.1