xref: /openbmc/u-boot/cmd/sata.c (revision e35171e9)
183d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+
22e192b24SSimon Glass /*
32e192b24SSimon Glass  * Copyright (C) 2000-2005, DENX Software Engineering
42e192b24SSimon Glass  *		Wolfgang Denk <wd@denx.de>
52e192b24SSimon Glass  * Copyright (C) Procsys. All rights reserved.
62e192b24SSimon Glass  *		Mushtaq Khan <mushtaq_k@procsys.com>
72e192b24SSimon Glass  *			<mushtaqk_921@yahoo.co.in>
82e192b24SSimon Glass  * Copyright (C) 2008 Freescale Semiconductor, Inc.
92e192b24SSimon Glass  *		Dave Liu <daveliu@freescale.com>
102e192b24SSimon Glass  */
112e192b24SSimon Glass 
122e192b24SSimon Glass #include <common.h>
13f19f1ecbSSimon Glass #include <ahci.h>
14f19f1ecbSSimon Glass #include <dm.h>
152e192b24SSimon Glass #include <command.h>
162e192b24SSimon Glass #include <part.h>
172e192b24SSimon Glass #include <sata.h>
18f19f1ecbSSimon Glass #include <dm/device-internal.h>
19f19f1ecbSSimon Glass #include <dm/uclass-internal.h>
202e192b24SSimon Glass 
212e192b24SSimon Glass static int sata_curr_device = -1;
222e192b24SSimon Glass 
sata_remove(int devnum)23f19f1ecbSSimon Glass int sata_remove(int devnum)
24f19f1ecbSSimon Glass {
25f19f1ecbSSimon Glass #ifdef CONFIG_AHCI
26f19f1ecbSSimon Glass 	struct udevice *dev;
27f19f1ecbSSimon Glass 	int rc;
28f19f1ecbSSimon Glass 
29f19f1ecbSSimon Glass 	rc = uclass_find_device(UCLASS_AHCI, devnum, &dev);
30f19f1ecbSSimon Glass 	if (!rc && !dev)
31f19f1ecbSSimon Glass 		rc = uclass_find_first_device(UCLASS_AHCI, &dev);
32f19f1ecbSSimon Glass 	if (rc || !dev) {
33f19f1ecbSSimon Glass 		printf("Cannot find SATA device %d (err=%d)\n", devnum, rc);
34f19f1ecbSSimon Glass 		return CMD_RET_FAILURE;
35f19f1ecbSSimon Glass 	}
36f19f1ecbSSimon Glass 
37f19f1ecbSSimon Glass 	rc = device_remove(dev, DM_REMOVE_NORMAL);
38f19f1ecbSSimon Glass 	if (rc) {
39f19f1ecbSSimon Glass 		printf("Cannot remove SATA device '%s' (err=%d)\n", dev->name,
40f19f1ecbSSimon Glass 		       rc);
41f19f1ecbSSimon Glass 		return CMD_RET_FAILURE;
42f19f1ecbSSimon Glass 	}
43f19f1ecbSSimon Glass 
44f19f1ecbSSimon Glass 	return 0;
45f19f1ecbSSimon Glass #else
46f19f1ecbSSimon Glass 	return sata_stop();
47f19f1ecbSSimon Glass #endif
48f19f1ecbSSimon Glass }
49f19f1ecbSSimon Glass 
sata_probe(int devnum)50f19f1ecbSSimon Glass int sata_probe(int devnum)
51f19f1ecbSSimon Glass {
52f19f1ecbSSimon Glass #ifdef CONFIG_AHCI
53f19f1ecbSSimon Glass 	struct udevice *dev;
54f19f1ecbSSimon Glass 	int rc;
55f19f1ecbSSimon Glass 
56f19f1ecbSSimon Glass 	rc = uclass_get_device(UCLASS_AHCI, devnum, &dev);
57f19f1ecbSSimon Glass 	if (rc)
58f19f1ecbSSimon Glass 		rc = uclass_find_first_device(UCLASS_AHCI, &dev);
59f19f1ecbSSimon Glass 	if (rc) {
60f19f1ecbSSimon Glass 		printf("Cannot probe SATA device %d (err=%d)\n", devnum, rc);
61f19f1ecbSSimon Glass 		return CMD_RET_FAILURE;
62f19f1ecbSSimon Glass 	}
63*b3860bfeSMarcel Ziswiler 	if (!dev) {
64*b3860bfeSMarcel Ziswiler 		printf("No SATA device found!\n");
65*b3860bfeSMarcel Ziswiler 		return CMD_RET_FAILURE;
66*b3860bfeSMarcel Ziswiler 	}
67f19f1ecbSSimon Glass 	rc = sata_scan(dev);
68f19f1ecbSSimon Glass 	if (rc) {
69f19f1ecbSSimon Glass 		printf("Cannot scan SATA device %d (err=%d)\n", devnum, rc);
70f19f1ecbSSimon Glass 		return CMD_RET_FAILURE;
71f19f1ecbSSimon Glass 	}
72f19f1ecbSSimon Glass 
73f19f1ecbSSimon Glass 	return 0;
74f19f1ecbSSimon Glass #else
75f19f1ecbSSimon Glass 	return sata_initialize() < 0 ? CMD_RET_FAILURE : CMD_RET_SUCCESS;
76f19f1ecbSSimon Glass #endif
77f19f1ecbSSimon Glass }
78f19f1ecbSSimon Glass 
do_sata(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])792e192b24SSimon Glass static int do_sata(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
802e192b24SSimon Glass {
812e192b24SSimon Glass 	int rc = 0;
822e192b24SSimon Glass 
83f19f1ecbSSimon Glass 	if (argc >= 2) {
84f19f1ecbSSimon Glass 		int devnum = 0;
852e192b24SSimon Glass 
86f19f1ecbSSimon Glass 		if (argc == 3)
87f19f1ecbSSimon Glass 			devnum = (int)simple_strtoul(argv[2], NULL, 10);
88f19f1ecbSSimon Glass 		if (!strcmp(argv[1], "stop"))
89f19f1ecbSSimon Glass 			return sata_remove(devnum);
902e192b24SSimon Glass 
91f19f1ecbSSimon Glass 		if (!strcmp(argv[1], "init")) {
92f19f1ecbSSimon Glass 			if (sata_curr_device != -1) {
93f19f1ecbSSimon Glass 				rc = sata_remove(devnum);
94f19f1ecbSSimon Glass 				if (rc)
95f19f1ecbSSimon Glass 					return rc;
96f19f1ecbSSimon Glass 			}
97f19f1ecbSSimon Glass 
98f19f1ecbSSimon Glass 			return sata_probe(devnum);
99f19f1ecbSSimon Glass 		}
1002e192b24SSimon Glass 	}
1012e192b24SSimon Glass 
1022e192b24SSimon Glass 	/* If the user has not yet run `sata init`, do it now */
103aa6ab905STang Yuantian 	if (sata_curr_device == -1) {
104f19f1ecbSSimon Glass 		rc = sata_probe(0);
1057e83f1d5STroy Kisky 		if (rc)
1067e83f1d5STroy Kisky 			return rc;
107f19f1ecbSSimon Glass 		sata_curr_device = 0;
108aa6ab905STang Yuantian 	}
1092e192b24SSimon Glass 
110e29e71e9SSimon Glass 	return blk_common_cmd(argc, argv, IF_TYPE_SATA, &sata_curr_device);
1112e192b24SSimon Glass }
1122e192b24SSimon Glass 
1132e192b24SSimon Glass U_BOOT_CMD(
1142e192b24SSimon Glass 	sata, 5, 1, do_sata,
1152e192b24SSimon Glass 	"SATA sub system",
1162e192b24SSimon Glass 	"init - init SATA sub system\n"
117f19f1ecbSSimon Glass 	"sata stop [dev] - disable SATA sub system or device\n"
1182e192b24SSimon Glass 	"sata info - show available SATA devices\n"
1192e192b24SSimon Glass 	"sata device [dev] - show or set current device\n"
1202e192b24SSimon Glass 	"sata part [dev] - print partition table\n"
1212e192b24SSimon Glass 	"sata read addr blk# cnt\n"
1222e192b24SSimon Glass 	"sata write addr blk# cnt"
1232e192b24SSimon Glass );
124