diff options
author | Dan Williams <dcbw@redhat.com> | 2008-08-18 15:40:02 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-08-26 20:06:30 -0400 |
commit | 3c34a5d821b825b720189e87561ba18500cf8026 (patch) | |
tree | e7c133cc220680f2beec71de24788a9ca6780133 /drivers/net/wireless | |
parent | c2d42545774c4bba7232521d836d0793330e3a4e (diff) |
atmel: return ENOENT on request_firmware failure
Return errors from request_firmware() (like other drivers that do
firmware load on device open) and make up plausible codes for other
error conditions. Gives userspace tools like NetworkManager a clue that
firmware may be missing when the result of setting IFF_UP is ENOENT.
Signed-off-by: Dan Williams <dcbw@redhat.com>
v2: fix reversed check of atmel_wakeup_firmware() in probe_atmel_card()
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r-- | drivers/net/wireless/atmel.c | 41 |
1 files changed, 22 insertions, 19 deletions
diff --git a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c index bd35bb0a1480..f23bcd07dee8 100644 --- a/drivers/net/wireless/atmel.c +++ b/drivers/net/wireless/atmel.c | |||
@@ -1304,7 +1304,7 @@ EXPORT_SYMBOL(atmel_open); | |||
1304 | int atmel_open(struct net_device *dev) | 1304 | int atmel_open(struct net_device *dev) |
1305 | { | 1305 | { |
1306 | struct atmel_private *priv = netdev_priv(dev); | 1306 | struct atmel_private *priv = netdev_priv(dev); |
1307 | int i, channel; | 1307 | int i, channel, err; |
1308 | 1308 | ||
1309 | /* any scheduled timer is no longer needed and might screw things up.. */ | 1309 | /* any scheduled timer is no longer needed and might screw things up.. */ |
1310 | del_timer_sync(&priv->management_timer); | 1310 | del_timer_sync(&priv->management_timer); |
@@ -1328,8 +1328,9 @@ int atmel_open(struct net_device *dev) | |||
1328 | priv->site_survey_state = SITE_SURVEY_IDLE; | 1328 | priv->site_survey_state = SITE_SURVEY_IDLE; |
1329 | priv->station_is_associated = 0; | 1329 | priv->station_is_associated = 0; |
1330 | 1330 | ||
1331 | if (!reset_atmel_card(dev)) | 1331 | err = reset_atmel_card(dev); |
1332 | return -EAGAIN; | 1332 | if (err) |
1333 | return err; | ||
1333 | 1334 | ||
1334 | if (priv->config_reg_domain) { | 1335 | if (priv->config_reg_domain) { |
1335 | priv->reg_domain = priv->config_reg_domain; | 1336 | priv->reg_domain = priv->config_reg_domain; |
@@ -3580,12 +3581,12 @@ static int atmel_wakeup_firmware(struct atmel_private *priv) | |||
3580 | 3581 | ||
3581 | if (i == 0) { | 3582 | if (i == 0) { |
3582 | printk(KERN_ALERT "%s: MAC failed to boot.\n", priv->dev->name); | 3583 | printk(KERN_ALERT "%s: MAC failed to boot.\n", priv->dev->name); |
3583 | return 0; | 3584 | return -EIO; |
3584 | } | 3585 | } |
3585 | 3586 | ||
3586 | if ((priv->host_info_base = atmel_read16(priv->dev, MR2)) == 0xffff) { | 3587 | if ((priv->host_info_base = atmel_read16(priv->dev, MR2)) == 0xffff) { |
3587 | printk(KERN_ALERT "%s: card missing.\n", priv->dev->name); | 3588 | printk(KERN_ALERT "%s: card missing.\n", priv->dev->name); |
3588 | return 0; | 3589 | return -ENODEV; |
3589 | } | 3590 | } |
3590 | 3591 | ||
3591 | /* now check for completion of MAC initialization through | 3592 | /* now check for completion of MAC initialization through |
@@ -3609,19 +3610,19 @@ static int atmel_wakeup_firmware(struct atmel_private *priv) | |||
3609 | if (i == 0) { | 3610 | if (i == 0) { |
3610 | printk(KERN_ALERT "%s: MAC failed to initialise.\n", | 3611 | printk(KERN_ALERT "%s: MAC failed to initialise.\n", |
3611 | priv->dev->name); | 3612 | priv->dev->name); |
3612 | return 0; | 3613 | return -EIO; |
3613 | } | 3614 | } |
3614 | 3615 | ||
3615 | /* Check for MAC_INIT_OK only on the register that the MAC_INIT_OK was set */ | 3616 | /* Check for MAC_INIT_OK only on the register that the MAC_INIT_OK was set */ |
3616 | if ((mr3 & MAC_INIT_COMPLETE) && | 3617 | if ((mr3 & MAC_INIT_COMPLETE) && |
3617 | !(atmel_read16(priv->dev, MR3) & MAC_INIT_OK)) { | 3618 | !(atmel_read16(priv->dev, MR3) & MAC_INIT_OK)) { |
3618 | printk(KERN_ALERT "%s: MAC failed MR3 self-test.\n", priv->dev->name); | 3619 | printk(KERN_ALERT "%s: MAC failed MR3 self-test.\n", priv->dev->name); |
3619 | return 0; | 3620 | return -EIO; |
3620 | } | 3621 | } |
3621 | if ((mr1 & MAC_INIT_COMPLETE) && | 3622 | if ((mr1 & MAC_INIT_COMPLETE) && |
3622 | !(atmel_read16(priv->dev, MR1) & MAC_INIT_OK)) { | 3623 | !(atmel_read16(priv->dev, MR1) & MAC_INIT_OK)) { |
3623 | printk(KERN_ALERT "%s: MAC failed MR1 self-test.\n", priv->dev->name); | 3624 | printk(KERN_ALERT "%s: MAC failed MR1 self-test.\n", priv->dev->name); |
3624 | return 0; | 3625 | return -EIO; |
3625 | } | 3626 | } |
3626 | 3627 | ||
3627 | atmel_copy_to_host(priv->dev, (unsigned char *)iface, | 3628 | atmel_copy_to_host(priv->dev, (unsigned char *)iface, |
@@ -3642,7 +3643,7 @@ static int atmel_wakeup_firmware(struct atmel_private *priv) | |||
3642 | iface->func_ctrl = le16_to_cpu(iface->func_ctrl); | 3643 | iface->func_ctrl = le16_to_cpu(iface->func_ctrl); |
3643 | iface->mac_status = le16_to_cpu(iface->mac_status); | 3644 | iface->mac_status = le16_to_cpu(iface->mac_status); |
3644 | 3645 | ||
3645 | return 1; | 3646 | return 0; |
3646 | } | 3647 | } |
3647 | 3648 | ||
3648 | /* determine type of memory and MAC address */ | 3649 | /* determine type of memory and MAC address */ |
@@ -3693,7 +3694,7 @@ static int probe_atmel_card(struct net_device *dev) | |||
3693 | /* Standard firmware in flash, boot it up and ask | 3694 | /* Standard firmware in flash, boot it up and ask |
3694 | for the Mac Address */ | 3695 | for the Mac Address */ |
3695 | priv->card_type = CARD_TYPE_SPI_FLASH; | 3696 | priv->card_type = CARD_TYPE_SPI_FLASH; |
3696 | if (atmel_wakeup_firmware(priv)) { | 3697 | if (atmel_wakeup_firmware(priv) == 0) { |
3697 | atmel_get_mib(priv, Mac_Address_Mib_Type, 0, dev->dev_addr, 6); | 3698 | atmel_get_mib(priv, Mac_Address_Mib_Type, 0, dev->dev_addr, 6); |
3698 | 3699 | ||
3699 | /* got address, now squash it again until the network | 3700 | /* got address, now squash it again until the network |
@@ -3835,6 +3836,7 @@ static int reset_atmel_card(struct net_device *dev) | |||
3835 | struct atmel_private *priv = netdev_priv(dev); | 3836 | struct atmel_private *priv = netdev_priv(dev); |
3836 | u8 configuration; | 3837 | u8 configuration; |
3837 | int old_state = priv->station_state; | 3838 | int old_state = priv->station_state; |
3839 | int err = 0; | ||
3838 | 3840 | ||
3839 | /* data to add to the firmware names, in priority order | 3841 | /* data to add to the firmware names, in priority order |
3840 | this implemenents firmware versioning */ | 3842 | this implemenents firmware versioning */ |
@@ -3868,11 +3870,12 @@ static int reset_atmel_card(struct net_device *dev) | |||
3868 | dev->name); | 3870 | dev->name); |
3869 | strcpy(priv->firmware_id, "atmel_at76c502.bin"); | 3871 | strcpy(priv->firmware_id, "atmel_at76c502.bin"); |
3870 | } | 3872 | } |
3871 | if (request_firmware(&fw_entry, priv->firmware_id, priv->sys_dev) != 0) { | 3873 | err = request_firmware(&fw_entry, priv->firmware_id, priv->sys_dev); |
3874 | if (err != 0) { | ||
3872 | printk(KERN_ALERT | 3875 | printk(KERN_ALERT |
3873 | "%s: firmware %s is missing, cannot continue.\n", | 3876 | "%s: firmware %s is missing, cannot continue.\n", |
3874 | dev->name, priv->firmware_id); | 3877 | dev->name, priv->firmware_id); |
3875 | return 0; | 3878 | return err; |
3876 | } | 3879 | } |
3877 | } else { | 3880 | } else { |
3878 | int fw_index = 0; | 3881 | int fw_index = 0; |
@@ -3901,7 +3904,7 @@ static int reset_atmel_card(struct net_device *dev) | |||
3901 | "%s: firmware %s is missing, cannot start.\n", | 3904 | "%s: firmware %s is missing, cannot start.\n", |
3902 | dev->name, priv->firmware_id); | 3905 | dev->name, priv->firmware_id); |
3903 | priv->firmware_id[0] = '\0'; | 3906 | priv->firmware_id[0] = '\0'; |
3904 | return 0; | 3907 | return -ENOENT; |
3905 | } | 3908 | } |
3906 | } | 3909 | } |
3907 | 3910 | ||
@@ -3926,8 +3929,9 @@ static int reset_atmel_card(struct net_device *dev) | |||
3926 | release_firmware(fw_entry); | 3929 | release_firmware(fw_entry); |
3927 | } | 3930 | } |
3928 | 3931 | ||
3929 | if (!atmel_wakeup_firmware(priv)) | 3932 | err = atmel_wakeup_firmware(priv); |
3930 | return 0; | 3933 | if (err != 0) |
3934 | return err; | ||
3931 | 3935 | ||
3932 | /* Check the version and set the correct flag for wpa stuff, | 3936 | /* Check the version and set the correct flag for wpa stuff, |
3933 | old and new firmware is incompatible. | 3937 | old and new firmware is incompatible. |
@@ -3968,10 +3972,9 @@ static int reset_atmel_card(struct net_device *dev) | |||
3968 | if (!priv->radio_on_broken) { | 3972 | if (!priv->radio_on_broken) { |
3969 | if (atmel_send_command_wait(priv, CMD_EnableRadio, NULL, 0) == | 3973 | if (atmel_send_command_wait(priv, CMD_EnableRadio, NULL, 0) == |
3970 | CMD_STATUS_REJECTED_RADIO_OFF) { | 3974 | CMD_STATUS_REJECTED_RADIO_OFF) { |
3971 | printk(KERN_INFO | 3975 | printk(KERN_INFO "%s: cannot turn the radio on.\n", |
3972 | "%s: cannot turn the radio on. (Hey radio, you're beautiful!)\n", | ||
3973 | dev->name); | 3976 | dev->name); |
3974 | return 0; | 3977 | return -EIO; |
3975 | } | 3978 | } |
3976 | } | 3979 | } |
3977 | 3980 | ||
@@ -4006,7 +4009,7 @@ static int reset_atmel_card(struct net_device *dev) | |||
4006 | wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL); | 4009 | wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL); |
4007 | } | 4010 | } |
4008 | 4011 | ||
4009 | return 1; | 4012 | return 0; |
4010 | } | 4013 | } |
4011 | 4014 | ||
4012 | static void atmel_send_command(struct atmel_private *priv, int command, | 4015 | static void atmel_send_command(struct atmel_private *priv, int command, |