diff options
| author | Ben Hutchings <bhutchings@solarflare.com> | 2012-11-27 23:38:10 -0500 |
|---|---|---|
| committer | Ben Hutchings <bhutchings@solarflare.com> | 2013-08-22 14:26:04 -0400 |
| commit | b766630b351c68c0383831dba9b81a905e5e84c6 (patch) | |
| tree | a76241779bfa03c7eabf0c9712d30cf0e23fb5e5 | |
| parent | ecd0a6f0f2c70a3b713bc77d8a32d6b4ad5ad49b (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.c | 279 | ||||
| -rw-r--r-- | drivers/net/ethernet/sfc/net_driver.h | 1 |
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 | ||
| 27 | struct efx_mtd_partition { | 27 | struct 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 | ||
| 50 | struct 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); | |||
| 73 | static int | 63 | static int |
| 74 | falcon_spi_slow_wait(struct efx_mtd_partition *part, bool uninterruptible) | 64 | falcon_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) | |||
| 135 | static int | 125 | static int |
| 136 | falcon_spi_erase(struct efx_mtd_partition *part, loff_t start, size_t len) | 126 | falcon_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 | ||
| 186 | static int efx_mtd_erase(struct mtd_info *mtd, struct erase_info *erase) | 175 | static 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) | |||
| 202 | static void efx_mtd_sync(struct mtd_info *mtd) | 191 | static 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 | ||
| 214 | static void efx_mtd_remove_partition(struct efx_mtd_partition *part) | 203 | static 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 | ||
| 227 | static void efx_mtd_remove_device(struct efx_mtd *efx_mtd) | 217 | static 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 | |||
| 237 | static 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 | ||
| 252 | static int efx_mtd_probe_device(struct efx_nic *efx, struct efx_mtd *efx_mtd) | 229 | static 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 | < | ||
