diff options
Diffstat (limited to 'drivers/staging/rtl8712/usb_intf.c')
-rw-r--r-- | drivers/staging/rtl8712/usb_intf.c | 38 |
1 files changed, 31 insertions, 7 deletions
diff --git a/drivers/staging/rtl8712/usb_intf.c b/drivers/staging/rtl8712/usb_intf.c index af28a62..a74e83d 100644 --- a/drivers/staging/rtl8712/usb_intf.c +++ b/drivers/staging/rtl8712/usb_intf.c @@ -28,6 +28,10 @@ #define _HCI_INTF_C_ +#include <linux/usb.h> +#include <linux/module.h> +#include <linux/firmware.h> + #include "osdep_service.h" #include "drv_types.h" #include "recv_osdep.h" @@ -100,6 +104,8 @@ static struct usb_device_id rtl871x_usb_id_tbl[] = { /* - */ {USB_DEVICE(0x20F4, 0x646B)}, {USB_DEVICE(0x083A, 0xC512)}, + {USB_DEVICE(0x25D4, 0x4CA1)}, + {USB_DEVICE(0x25D4, 0x4CAB)}, /* RTL8191SU */ /* Realtek */ @@ -357,6 +363,10 @@ static u8 key_2char2num(u8 hch, u8 lch) return (hex_to_bin(hch) << 4) | hex_to_bin(lch); } +static const struct device_type wlan_type = { + .name = "wlan", +}; + /* * drv_init() - a device potentially for us * @@ -370,25 +380,29 @@ static int r871xu_drv_init(struct usb_interface *pusb_intf, struct _adapter *padapter = NULL; struct dvobj_priv *pdvobjpriv; struct net_device *pnetdev; + struct usb_device *udev; printk(KERN_INFO "r8712u: DriverVersion: %s\n", DRVER); /* In this probe function, O.S. will provide the usb interface pointer * to driver. We have to increase the reference count of the usb device * structure by using the usb_get_dev function. */ - usb_get_dev(interface_to_usbdev(pusb_intf)); + udev = interface_to_usbdev(pusb_intf); + usb_get_dev(udev); pintf = pusb_intf; /* step 1. */ pnetdev = r8712_init_netdev(); if (!pnetdev) goto error; - padapter = (struct _adapter *)_netdev_priv(pnetdev); + padapter = netdev_priv(pnetdev); disable_ht_for_spec_devid(pdid, padapter); pdvobjpriv = &padapter->dvobjpriv; pdvobjpriv->padapter = padapter; - padapter->dvobjpriv.pusbdev = interface_to_usbdev(pusb_intf); + padapter->dvobjpriv.pusbdev = udev; + padapter->pusb_intf = pusb_intf; usb_set_intfdata(pusb_intf, pnetdev); SET_NETDEV_DEV(pnetdev, &pusb_intf->dev); + pnetdev->dev.type = &wlan_type; /* step 2. */ padapter->dvobj_init = &r8712_usb_dvobj_init; padapter->dvobj_deinit = &r8712_usb_dvobj_deinit; @@ -593,17 +607,19 @@ static int r871xu_drv_init(struct usb_interface *pusb_intf, "%pM\n", mac); memcpy(pnetdev->dev_addr, mac, ETH_ALEN); } - /* step 6. Tell the network stack we exist */ - if (register_netdev(pnetdev) != 0) + /* step 6. Load the firmware asynchronously */ + if (rtl871x_load_fw(padapter)) goto error; + spin_lock_init(&padapter->lockRxFF0Filter); + mutex_init(&padapter->mutex_start); return 0; error: - usb_put_dev(interface_to_usbdev(pusb_intf)); + usb_put_dev(udev); usb_set_intfdata(pusb_intf, NULL); if (padapter->dvobj_deinit != NULL) padapter->dvobj_deinit(padapter); if (pnetdev) - os_free_netdev(pnetdev); + free_netdev(pnetdev); return -ENODEV; } @@ -615,6 +631,11 @@ static void r871xu_dev_remove(struct usb_interface *pusb_intf) struct _adapter *padapter = netdev_priv(pnetdev); struct usb_device *udev = interface_to_usbdev(pusb_intf); + if (padapter->fw_found) + release_firmware(padapter->fw); + /* never exit with a firmware callback pending */ + wait_for_completion(&padapter->rtl8712_fw_ready); + usb_set_intfdata(pusb_intf, NULL); if (padapter) { if (drvpriv.drv_registered == true) padapter->bSurpriseRemoved = true; @@ -624,6 +645,9 @@ static void r871xu_dev_remove(struct usb_interface *pusb_intf) } flush_scheduled_work(); udelay(1); + /*Stop driver mlme relation timer */ + if (padapter->fw_found) + r8712_stop_drv_timers(padapter); r871x_dev_unload(padapter); r8712_free_drv_sw(padapter); } |