aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/e100.c
diff options
context:
space:
mode:
authorDavid Graham <david.graham@intel.com>2009-10-28 07:13:57 -0400
committerDavid S. Miller <davem@davemloft.net>2009-10-28 07:13:57 -0400
commit7e15b0c9991dfe0bf05a2f8fab9154bb7827622e (patch)
tree113ef96d0785c6da9dbbc40473a7664553604088 /drivers/net/e100.c
parentc70948105d4f057b90d4a587246565782e51ed35 (diff)
e100: Fix to allow systems with FW based cards to resume from STD
Devices with loadable firmware must have their firmware reloaded after the system resumes from sleep, but the request_firmare() API is not available at this point in the resume flow because tasks are not yet running, and the system will hang if it is called. Work around this issue by only calling request_firmware() for a device's first firmware load, and cache a copy of the pointer to the firmware blob for that device, so that we may reload firmware images even during resume. Signed-off-by: David Graham <david.graham@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/e100.c')
-rw-r--r--drivers/net/e100.c20
1 files changed, 16 insertions, 4 deletions
diff --git a/drivers/net/e100.c b/drivers/net/e100.c
index ff83efd47b0d..f428c5f72f18 100644
--- a/drivers/net/e100.c
+++ b/drivers/net/e100.c
@@ -621,6 +621,7 @@ struct nic {
621 u16 eeprom_wc; 621 u16 eeprom_wc;
622 __le16 eeprom[256]; 622 __le16 eeprom[256];
623 spinlock_t mdio_lock; 623 spinlock_t mdio_lock;
624 const struct firmware *fw;
624}; 625};
625 626
626static inline void e100_write_flush(struct nic *nic) 627static inline void e100_write_flush(struct nic *nic)
@@ -1222,9 +1223,9 @@ static void e100_configure(struct nic *nic, struct cb *cb, struct sk_buff *skb)
1222static const struct firmware *e100_request_firmware(struct nic *nic) 1223static const struct firmware *e100_request_firmware(struct nic *nic)
1223{ 1224{
1224 const char *fw_name; 1225 const char *fw_name;
1225 const struct firmware *fw; 1226 const struct firmware *fw = nic->fw;
1226 u8 timer, bundle, min_size; 1227 u8 timer, bundle, min_size;
1227 int err; 1228 int err = 0;
1228 1229
1229 /* do not load u-code for ICH devices */ 1230 /* do not load u-code for ICH devices */
1230 if (nic->flags & ich) 1231 if (nic->flags & ich)
@@ -1240,12 +1241,20 @@ static const struct firmware *e100_request_firmware(struct nic *nic)
1240 else /* No ucode on other devices */ 1241 else /* No ucode on other devices */
1241 return NULL; 1242 return NULL;
1242 1243
1243 err = request_firmware(&fw, fw_name, &nic->pdev->dev); 1244 /* If the firmware has not previously been loaded, request a pointer
1245 * to it. If it was previously loaded, we are reinitializing the
1246 * adapter, possibly in a resume from hibernate, in which case
1247 * request_firmware() cannot be used.
1248 */
1249 if (!fw)
1250 err = request_firmware(&fw, fw_name, &nic->pdev->dev);
1251
1244 if (err) { 1252 if (err) {
1245 DPRINTK(PROBE, ERR, "Failed to load firmware \"%s\": %d\n", 1253 DPRINTK(PROBE, ERR, "Failed to load firmware \"%s\": %d\n",
1246 fw_name, err); 1254 fw_name, err);
1247 return ERR_PTR(err); 1255 return ERR_PTR(err);
1248 } 1256 }
1257
1249 /* Firmware should be precisely UCODE_SIZE (words) plus three bytes 1258 /* Firmware should be precisely UCODE_SIZE (words) plus three bytes
1250 indicating the offsets for BUNDLESMALL, BUNDLEMAX, INTDELAY */ 1259 indicating the offsets for BUNDLESMALL, BUNDLEMAX, INTDELAY */
1251 if (fw->size != UCODE_SIZE * 4 + 3) { 1260 if (fw->size != UCODE_SIZE * 4 + 3) {
@@ -1268,7 +1277,10 @@ static const struct firmware *e100_request_firmware(struct nic *nic)
1268 release_firmware(fw); 1277 release_firmware(fw);
1269 return ERR_PTR(-EINVAL); 1278 return ERR_PTR(-EINVAL);
1270 } 1279 }
1271 /* OK, firmware is validated and ready to use... */ 1280
1281 /* OK, firmware is validated and ready to use. Save a pointer
1282 * to it in the nic */
1283 nic->fw = fw;
1272 return fw; 1284 return fw;
1273} 1285}
1274 1286