Skip to content

Commit

Permalink
rtlwifi: unbind driver if firmware can't be found
Browse files Browse the repository at this point in the history
Signed-off-by: Christian Lamparter <[email protected]>
  • Loading branch information
chunkeey committed Jan 8, 2015
1 parent 49495e1 commit 23aeda7
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 5 deletions.
24 changes: 24 additions & 0 deletions rtlwifi/pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -2390,6 +2390,29 @@ void rtl_pci_disconnect(struct pci_dev *pdev)
}
EXPORT_SYMBOL(rtl_pci_disconnect);

static void rtl_pci_unbind(struct ieee80211_hw *hw)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
struct device *parent = rtlpci->pdev->dev.parent;
struct pci_dev *pdev;

/* Store a copy of the pci_device pointer locally.
* This is because device_release_driver initiates
* rtl_pci_disconnect, which in turn frees our
* driver context (rtl_priv).
*/
pdev = rtlpci->pdev;

/* unbind anything failed */
if (parent)
device_lock(parent);

device_release_driver(&pdev->dev);
if (parent)
device_unlock(parent);
}

#ifdef CONFIG_PM_SLEEP
/***************************************
kernel pci power state define:
Expand Down Expand Up @@ -2436,6 +2459,7 @@ struct rtl_intf_ops rtl_pci_ops = {
.read_efuse_byte = read_efuse_byte,
.adapter_start = rtl_pci_start,
.adapter_stop = rtl_pci_stop,
.adapter_unbind = rtl_pci_unbind,
.check_buddy_priv = rtl_pci_check_buddy_priv,
.adapter_tx = rtl_pci_tx,
.flush = rtl_pci_flush,
Expand Down
14 changes: 9 additions & 5 deletions rtlwifi/rtl8192s/fw_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,20 +42,24 @@ void rtl92s_fw_cb(const struct firmware *firmware, void *context)
complete(&rtlpriv->firmware_loading_complete);
if (!firmware) {
pr_err("Firmware %s not available\n", rtlpriv->cfg->fw_name);
rtlpriv->max_fw_size = 0;
return;
goto bad_fw;
}
if (firmware->size > rtlpriv->max_fw_size) {
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
"Firmware is too big!\n");
rtlpriv->max_fw_size = 0;
release_firmware(firmware);
return;
goto bad_fw;
}

pfirmware = (struct rt_firmware *)rtlpriv->rtlhal.pfirmware;
memcpy(pfirmware->sz_fw_tmpbuffer, firmware->data, firmware->size);
pfirmware->sz_fw_tmpbufferlen = firmware->size;
release_firmware(firmware);
return;

bad_fw:
rtlpriv->max_fw_size = 0;
release_firmware(firmware);
rtlpriv->intf_ops->adapter_unbind(hw);
}
EXPORT_SYMBOL_GPL(rtl92s_fw_cb);

Expand Down
24 changes: 24 additions & 0 deletions rtlwifi/usb.c
Original file line number Diff line number Diff line change
Expand Up @@ -816,6 +816,29 @@ static void rtl_usb_cleanup(struct ieee80211_hw *hw)
usb_kill_anchored_urbs(&rtlusb->tx_submitted);
}

static void rtl_usb_unbind(struct ieee80211_hw *hw)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw));
struct device *parent = rtlusb->udev->dev.parent;
struct usb_device *udev;

/* Store a copy of the usb_device pointer locally.
* This is because device_release_driver initiates
* rtl_usb_disconnect, which in turn frees our
* driver context (rtl_priv).
*/
udev = rtlusb->udev;

/* unbind anything failed */
if (parent)
device_lock(parent);

device_release_driver(&udev->dev);
if (parent)
device_unlock(parent);
}

/**
*
* We may add some struct into struct rtl_usb later. Do deinit here.
Expand Down Expand Up @@ -1105,6 +1128,7 @@ static struct rtl_intf_ops rtl_usb_ops = {
.adapter_start = rtl_usb_start,
.adapter_stop = rtl_usb_stop,
.adapter_tx = rtl_usb_tx,
.adapter_unbind = rtl_usb_unbind,
.waitq_insert = rtl_usb_tx_chk_waitq_insert,
};

Expand Down
1 change: 1 addition & 0 deletions rtlwifi/wifi.h
Original file line number Diff line number Diff line change
Expand Up @@ -2200,6 +2200,7 @@ struct rtl_intf_ops {
void (*read_efuse_byte)(struct ieee80211_hw *hw, u16 _offset, u8 *pbuf);
int (*adapter_start) (struct ieee80211_hw *hw);
void (*adapter_stop) (struct ieee80211_hw *hw);
void (*adapter_unbind) (struct ieee80211_hw *hw);
bool (*check_buddy_priv)(struct ieee80211_hw *hw,
struct rtl_priv **buddy_priv);

Expand Down

0 comments on commit 23aeda7

Please sign in to comment.