Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 | // SPDX-License-Identifier: GPL-2.0+ /* * (C) Copyright 2008-2011 Freescale Semiconductor, Inc. */ /* #define DEBUG */ #include <asm/global_data.h> #include <command.h> #include <env.h> #include <env_internal.h> #include <fdtdec.h> #include <linux/stddef.h> #include <malloc.h> #include <memalign.h> #include <part.h> #include <search.h> #include <scsi.h> #include <errno.h> #include <dm/ofnode.h> DECLARE_GLOBAL_DATA_PTR; static env_t envbuf; struct env_scsi_info { struct blk_desc *blk; struct disk_partition part; int count; }; static struct env_scsi_info env_part; static inline struct env_scsi_info *env_scsi_get_part(void) { static bool is_scsi_scanned; struct env_scsi_info *ep = &env_part; if (!is_scsi_scanned) { scsi_scan(false /* no verbose */); is_scsi_scanned = true; } if (CONFIG_ENV_SCSI_PART_UUID[0] == '\0') { if (blk_get_device_part_str("scsi", CONFIG_ENV_SCSI_HW_PARTITION, &ep->blk, &ep->part, true)) return NULL; } else { if (scsi_get_blk_by_uuid(CONFIG_ENV_SCSI_PART_UUID, &ep->blk, &ep->part)) return NULL; } ep->count = CONFIG_ENV_SIZE / ep->part.blksz; return ep; } static int env_scsi_save(void) { struct env_scsi_info *ep = env_scsi_get_part(); int ret; if (!ep) return -ENOENT; ret = env_export(&envbuf); if (ret) return ret; if (blk_dwrite(ep->blk, ep->part.start, ep->count, &envbuf) != ep->count) return -EIO; return 0; } static int env_scsi_erase(void) { struct env_scsi_info *ep = env_scsi_get_part(); if (!ep) return -ENOENT; return (int)blk_derase(ep->blk, ep->part.start, ep->count); } #if defined(ENV_IS_EMBEDDED) static int env_scsi_load(void) { return 0; } #else static int env_scsi_load(void) { struct env_scsi_info *ep = env_scsi_get_part(); int ret; if (!ep) { if (CONFIG_ENV_SCSI_PART_UUID[0] == '\0') env_set_default("SCSI partition " CONFIG_ENV_SCSI_HW_PARTITION " not found", 0); else env_set_default(CONFIG_ENV_SCSI_PART_UUID " partition not found", 0); return -ENOENT; } if (blk_dread(ep->blk, ep->part.start, ep->count, &envbuf) != ep->count) { if (CONFIG_ENV_SCSI_PART_UUID[0] == '\0') env_set_default("SCSI partition " CONFIG_ENV_SCSI_HW_PARTITION " read failed", 0); else env_set_default(CONFIG_ENV_SCSI_PART_UUID " partition read failed", 0); return -EIO; } ret = env_import((char *)&envbuf, 1, H_EXTERNAL); if (ret) { debug("ENV import failed\n"); env_set_default("Cannot load environment", 0); } else { gd->env_addr = (ulong)envbuf.data; } return ret; } #endif U_BOOT_ENV_LOCATION(scsi) = { .location = ENVL_SCSI, ENV_NAME("SCSI") .load = env_scsi_load, .save = ENV_SAVE_PTR(env_scsi_save), .erase = ENV_ERASE_PTR(env_scsi_erase), }; |