aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBen Hutchings <bhutchings@solarflare.com>2012-11-27 23:38:10 -0500
committerBen Hutchings <bhutchings@solarflare.com>2013-08-22 14:26:04 -0400
commitb766630b351c68c0383831dba9b81a905e5e84c6 (patch)
treea76241779bfa03c7eabf0c9712d30cf0e23fb5e5
parentecd0a6f0f2c70a3b713bc77d8a32d6b4ad5ad49b (diff)
sfc: Eliminate struct efx_mtd
Currently we use struct efx_mtd to represent a physical NVRAM device and struct efx_mtd_partition to represent a partition on that device. But this only really makes sense for Falcon, as we don't know or care whether MC-managed NVRAM partitions are on one or more physical devices. It complicates iteration and provides little benefit. Therefore: - Replace the pointer to efx_mtd in mtd_info::priv with a pointer to efx_nic - Move the falcon_spi_device pointer into the union in struct efx_mtd_partition - Move the device name to efx_mtd_partition::dev_type_name - Move the efx_mtd_ops pointer to efx_nic::mtd_ops - Make efx_nic::mtd_list a list of partitions Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
-rw-r--r--drivers/net/ethernet/sfc/mtd.c279
-rw-r--r--drivers/net/ethernet/sfc/net_driver.h1
2 files changed, 120 insertions, 160 deletions
diff --git a/drivers/net/ethernet/sfc/mtd.c b/drivers/net/ethernet/sfc/mtd.c
index e4b35c61e90b..ba6c87a73d86 100644
--- a/drivers/net/ethernet/sfc/mtd.c
+++ b/drivers/net/ethernet/sfc/mtd.c
@@ -25,6 +25,7 @@
25#define FALCON_SPI_VERIFY_BUF_LEN 16 25#define FALCON_SPI_VERIFY_BUF_LEN 16
26 26
27struct efx_mtd_partition { 27struct efx_mtd_partition {
28 struct list_head node;
28 struct mtd_info mtd; 29 struct mtd_info mtd;
29 union { 30 union {
30 struct { 31 struct {
@@ -32,8 +33,12 @@ struct efx_mtd_partition {
32 u8 nvram_type; 33 u8 nvram_type;
33 u16 fw_subtype; 34 u16 fw_subtype;
34 } mcdi; 35 } mcdi;
35 size_t offset; 36 struct {
37 const struct falcon_spi_device *spi;
38 size_t offset;
39 } falcon;
36 }; 40 };
41 const char *dev_type_name;
37 const char *type_name; 42 const char *type_name;
38 char name[IFNAMSIZ + 20]; 43 char name[IFNAMSIZ + 20];
39}; 44};
@@ -47,21 +52,6 @@ struct efx_mtd_ops {
47 int (*sync)(struct mtd_info *mtd); 52 int (*sync)(struct mtd_info *mtd);
48}; 53};
49 54
50struct efx_mtd {
51 struct list_head node;
52 struct efx_nic *efx;
53 const struct falcon_spi_device *spi;
54 const char *name;
55 const struct efx_mtd_ops *ops;
56 size_t n_parts;
57 struct efx_mtd_partition part[0];
58};
59
60#define efx_for_each_partition(part, efx_mtd) \
61 for ((part) = &(efx_mtd)->part[0]; \
62 (part) != &(efx_mtd)->part[(efx_mtd)->n_parts]; \
63 (part)++)
64
65#define to_efx_mtd_partition(mtd) \ 55#define to_efx_mtd_partition(mtd) \
66 container_of(mtd, struct efx_mtd_partition, mtd) 56 container_of(mtd, struct efx_mtd_partition, mtd)
67 57
@@ -73,9 +63,8 @@ static int siena_mtd_probe(struct efx_nic *efx);
73static int 63static int
74falcon_spi_slow_wait(struct efx_mtd_partition *part, bool uninterruptible) 64falcon_spi_slow_wait(struct efx_mtd_partition *part, bool uninterruptible)
75{ 65{
76 struct efx_mtd *efx_mtd = part->mtd.priv; 66 const struct falcon_spi_device *spi = part->falcon.spi;
77 const struct falcon_spi_device *spi = efx_mtd->spi; 67 struct efx_nic *efx = part->mtd.priv;
78 struct efx_nic *efx = efx_mtd->efx;
79 u8 status; 68 u8 status;
80 int rc, i; 69 int rc, i;
81 70
@@ -93,7 +82,8 @@ falcon_spi_slow_wait(struct efx_mtd_partition *part, bool uninterruptible)
93 if (signal_pending(current)) 82 if (signal_pending(current))
94 return -EINTR; 83 return -EINTR;
95 } 84 }
96 pr_err("%s: timed out waiting for %s\n", part->name, efx_mtd->name); 85 pr_err("%s: timed out waiting for %s\n",
86 part->name, part->dev_type_name);
97 return -ETIMEDOUT; 87 return -ETIMEDOUT;
98} 88}
99 89
@@ -135,9 +125,8 @@ falcon_spi_unlock(struct efx_nic *efx, const struct falcon_spi_device *spi)
135static int 125static int
136falcon_spi_erase(struct efx_mtd_partition *part, loff_t start, size_t len) 126falcon_spi_erase(struct efx_mtd_partition *part, loff_t start, size_t len)
137{ 127{
138 struct efx_mtd *efx_mtd = part->mtd.priv; 128 const struct falcon_spi_device *spi = part->falcon.spi;
139 const struct falcon_spi_device *spi = efx_mtd->spi; 129 struct efx_nic *efx = part->mtd.priv;
140 struct efx_nic *efx = efx_mtd->efx;
141 unsigned pos, block_len; 130 unsigned pos, block_len;
142 u8 empty[FALCON_SPI_VERIFY_BUF_LEN]; 131 u8 empty[FALCON_SPI_VERIFY_BUF_LEN];
143 u8 buffer[FALCON_SPI_VERIFY_BUF_LEN]; 132 u8 buffer[FALCON_SPI_VERIFY_BUF_LEN];
@@ -185,10 +174,10 @@ falcon_spi_erase(struct efx_mtd_partition *part, loff_t start, size_t len)
185 174
186static int efx_mtd_erase(struct mtd_info *mtd, struct erase_info *erase) 175static int efx_mtd_erase(struct mtd_info *mtd, struct erase_info *erase)
187{ 176{
188 struct efx_mtd *efx_mtd = mtd->priv; 177 struct efx_nic *efx = mtd->priv;
189 int rc; 178 int rc;
190 179
191 rc = efx_mtd->ops->erase(mtd, erase->addr, erase->len); 180 rc = efx->mtd_ops->erase(mtd, erase->addr, erase->len);
192 if (rc == 0) { 181 if (rc == 0) {
193 erase->state = MTD_ERASE_DONE; 182 erase->state = MTD_ERASE_DONE;
194 } else { 183 } else {
@@ -202,13 +191,13 @@ static int efx_mtd_erase(struct mtd_info *mtd, struct erase_info *erase)
202static void efx_mtd_sync(struct mtd_info *mtd) 191static void efx_mtd_sync(struct mtd_info *mtd)
203{ 192{
204 struct efx_mtd_partition *part = to_efx_mtd_partition(mtd); 193 struct efx_mtd_partition *part = to_efx_mtd_partition(mtd);
205 struct efx_mtd *efx_mtd = mtd->priv; 194 struct efx_nic *efx = mtd->priv;
206 int rc; 195 int rc;
207 196
208 rc = efx_mtd->ops->sync(mtd); 197 rc = efx->mtd_ops->sync(mtd);
209 if (rc) 198 if (rc)
210 pr_err("%s: %s sync failed (%d)\n", 199 pr_err("%s: %s sync failed (%d)\n",
211 part->name, efx_mtd->name, rc); 200 part->name, part->dev_type_name, rc);
212} 201}
213 202
214static void efx_mtd_remove_partition(struct efx_mtd_partition *part) 203static void efx_mtd_remove_partition(struct efx_mtd_partition *part)
@@ -222,86 +211,84 @@ static void efx_mtd_remove_partition(struct efx_mtd_partition *part)
222 ssleep(1); 211 ssleep(1);
223 } 212 }
224 WARN_ON(rc); 213 WARN_ON(rc);
214 list_del(&part->node);
225} 215}
226 216
227static void efx_mtd_remove_device(struct efx_mtd *efx_mtd) 217static void efx_mtd_rename_partition(struct efx_mtd_partition *part)
228{
229 struct efx_mtd_partition *part;
230
231 efx_for_each_partition(part, efx_mtd)
232 efx_mtd_remove_partition(part);
233 list_del(&efx_mtd->node);
234 kfree(efx_mtd);
235}
236
237static void efx_mtd_rename_device(struct efx_mtd *efx_mtd)
238{ 218{
239 struct efx_mtd_partition *part; 219 struct efx_nic *efx = part->mtd.priv;
240 220
241 efx_for_each_partition(part, efx_mtd) 221 if (efx_nic_rev(efx) >= EFX_REV_SIENA_A0)
242 if (efx_nic_rev(efx_mtd->efx) >= EFX_REV_SIENA_A0) 222 snprintf(part->name, sizeof(part->name), "%s %s:%02x",
243 snprintf(part->name, sizeof(part->name), 223 efx->name, part->type_name, part->mcdi.fw_subtype);
244 "%s %s:%02x", efx_mtd->efx->name, 224 else
245 part->type_name, part->mcdi.fw_subtype); 225 snprintf(part->name, sizeof(part->name), "%s %s",
246 else 226 efx->name, part->type_name);
247 snprintf(part->name, sizeof(part->name),
248 "%s %s", efx_mtd->efx->name,
249 part->type_name);
250} 227}
251 228
252static int efx_mtd_probe_device(struct efx_nic *efx, struct efx_mtd *efx_mtd) 229static int efx_mtd_add(struct efx_nic *efx,
230 struct efx_mtd_partition *parts, size_t n_parts)
253{ 231{
254 struct efx_mtd_partition *part; 232 struct efx_mtd_partition *part;
233 size_t i;
255 234
256 efx_mtd->efx = efx; 235 for (i = 0; i < n_parts; i++) {
236 part = &parts[i];
257 237
258 efx_mtd_rename_device(efx_mtd);
259
260 efx_for_each_partition(part, efx_mtd) {
261 part->mtd.writesize = 1; 238 part->mtd.writesize = 1;
262 <