Home | History | Annotate | Download | only in env
      1 // SPDX-License-Identifier: GPL-2.0+
      2 /*
      3  * (C) Copyright 2010-2016 Freescale Semiconductor, Inc.
      4  */
      5 
      6 /* #define DEBUG */
      7 
      8 #include <common.h>
      9 
     10 #include <command.h>
     11 #include <environment.h>
     12 #include <linux/stddef.h>
     13 #include <errno.h>
     14 #include <memalign.h>
     15 #include <sata.h>
     16 #include <search.h>
     17 
     18 #if defined(CONFIG_ENV_SIZE_REDUND) || defined(CONFIG_ENV_OFFSET_REDUND)
     19 #error ENV REDUND not supported
     20 #endif
     21 
     22 #if !defined(CONFIG_ENV_OFFSET) || !defined(CONFIG_ENV_SIZE)
     23 #error CONFIG_ENV_OFFSET or CONFIG_ENV_SIZE not defined
     24 #endif
     25 
     26 __weak int sata_get_env_dev(void)
     27 {
     28 	return CONFIG_SYS_SATA_ENV_DEV;
     29 }
     30 
     31 #ifdef CONFIG_CMD_SAVEENV
     32 static inline int write_env(struct blk_desc *sata, unsigned long size,
     33 			    unsigned long offset, void *buffer)
     34 {
     35 	uint blk_start, blk_cnt, n;
     36 
     37 	blk_start = ALIGN(offset, sata->blksz) / sata->blksz;
     38 	blk_cnt   = ALIGN(size, sata->blksz) / sata->blksz;
     39 
     40 	n = blk_dwrite(sata, blk_start, blk_cnt, buffer);
     41 
     42 	return (n == blk_cnt) ? 0 : -1;
     43 }
     44 
     45 static int env_sata_save(void)
     46 {
     47 	ALLOC_CACHE_ALIGN_BUFFER(env_t, env_new, 1);
     48 	struct blk_desc *sata = NULL;
     49 	int env_sata, ret;
     50 
     51 	if (sata_initialize())
     52 		return 1;
     53 
     54 	env_sata = sata_get_env_dev();
     55 
     56 	sata = sata_get_dev(env_sata);
     57 	if (sata == NULL) {
     58 		printf("Unknown SATA(%d) device for environment!\n",
     59 		       env_sata);
     60 		return 1;
     61 	}
     62 
     63 	ret = env_export(env_new);
     64 	if (ret)
     65 		return 1;
     66 
     67 	printf("Writing to SATA(%d)...", env_sata);
     68 	if (write_env(sata, CONFIG_ENV_SIZE, CONFIG_ENV_OFFSET, &env_new)) {
     69 		puts("failed\n");
     70 		return 1;
     71 	}
     72 
     73 	puts("done\n");
     74 	return 0;
     75 }
     76 #endif /* CONFIG_CMD_SAVEENV */
     77 
     78 static inline int read_env(struct blk_desc *sata, unsigned long size,
     79 			   unsigned long offset, void *buffer)
     80 {
     81 	uint blk_start, blk_cnt, n;
     82 
     83 	blk_start = ALIGN(offset, sata->blksz) / sata->blksz;
     84 	blk_cnt   = ALIGN(size, sata->blksz) / sata->blksz;
     85 
     86 	n = blk_dread(sata, blk_start, blk_cnt, buffer);
     87 
     88 	return (n == blk_cnt) ? 0 : -1;
     89 }
     90 
     91 static void env_sata_load(void)
     92 {
     93 	ALLOC_CACHE_ALIGN_BUFFER(char, buf, CONFIG_ENV_SIZE);
     94 	struct blk_desc *sata = NULL;
     95 	int env_sata;
     96 
     97 	if (sata_initialize())
     98 		return -EIO;
     99 
    100 	env_sata = sata_get_env_dev();
    101 
    102 	sata = sata_get_dev(env_sata);
    103 	if (sata == NULL) {
    104 		printf("Unknown SATA(%d) device for environment!\n", env_sata);
    105 		return -EIO;
    106 	}
    107 
    108 	if (read_env(sata, CONFIG_ENV_SIZE, CONFIG_ENV_OFFSET, buf)) {
    109 		set_default_env(NULL);
    110 		return -EIO;
    111 	}
    112 
    113 	return env_import(buf, 1);
    114 }
    115 
    116 U_BOOT_ENV_LOCATION(sata) = {
    117 	.location	= ENVL_ESATA,
    118 	ENV_NAME("SATA")
    119 	.load		= env_sata_load,
    120 	.save		= env_save_ptr(env_sata_save),
    121 };
    122