Commit 8cb652bb authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'staging-3.15-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging

Pull staging driver fixes from Greg KH:
 "Here are a few staging driver fixes for issues that have been reported
  for 3.15-rc2.

  Also dominating the diffstat for the pull request is the removal of
  the rtl8187se driver.  It's no longer needed in staging as a "real"
  driver for this hardware is now merged in the tree in the "correct"
  location in drivers/net/

  All of these patches have been tested in linux-next"

* tag 'staging-3.15-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging:
  staging: r8188eu: Fix case where ethtype was never obtained and always be checked against 0
  staging: r8712u: Fix case where ethtype was never obtained and always be checked against 0
  staging: r8188eu: Calling rtw_get_stainfo() with a NULL sta_addr will return NULL
  staging: comedi: fix circular locking dependency in comedi_mmap()
  staging: r8723au: Add missing initialization of change_inx in sort algorithm
  Staging: unisys: use after free in list_for_each()
  staging: unisys: use after free in error messages
  staging: speakup: fix misuse of kstrtol() in handle_goto()
  staging: goldfish: Call free_irq in error path
  staging: delete rtl8187se wireless driver
  staging: rtl8723au: Fix buffer overflow in rtw_get_wfd_ie()
  staging: gs_fpgaboot: remove __TIMESTAMP__ macro
  staging: vme: fix memory leak in vme_user_probe()
  staging: fpgaboot: clean up Makefile
  staging/usbip: fix store_attach() sscanf return value check
  staging/usbip: userspace - fix usbipd SIGSEGV from refresh_exported_devices()
  staging: rtl8188eu: remove spaces, correct counts to unbreak P2P ioctls
  staging/rtl8821ae: Fix OOM handling in _rtl_init_deferred_work()
parents 575a2929 33c84bc1
......@@ -40,8 +40,6 @@ source "drivers/staging/olpc_dcon/Kconfig"
source "drivers/staging/panel/Kconfig"
source "drivers/staging/rtl8187se/Kconfig"
source "drivers/staging/rtl8192u/Kconfig"
source "drivers/staging/rtl8192e/Kconfig"
......
......@@ -12,7 +12,6 @@ obj-$(CONFIG_PRISM2_USB) += wlan-ng/
obj-$(CONFIG_COMEDI) += comedi/
obj-$(CONFIG_FB_OLPC_DCON) += olpc_dcon/
obj-$(CONFIG_PANEL) += panel/
obj-$(CONFIG_R8187SE) += rtl8187se/
obj-$(CONFIG_RTL8192U) += rtl8192u/
obj-$(CONFIG_RTL8192E) += rtl8192e/
obj-$(CONFIG_R8712U) += rtl8712/
......
......@@ -61,6 +61,8 @@ static void __comedi_buf_free(struct comedi_device *dev,
struct comedi_subdevice *s)
{
struct comedi_async *async = s->async;
struct comedi_buf_map *bm;
unsigned long flags;
if (async->prealloc_buf) {
vunmap(async->prealloc_buf);
......@@ -68,8 +70,11 @@ static void __comedi_buf_free(struct comedi_device *dev,
async->prealloc_bufsz = 0;
}
comedi_buf_map_put(async->buf_map);
spin_lock_irqsave(&s->spin_lock, flags);
bm = async->buf_map;
async->buf_map = NULL;
spin_unlock_irqrestore(&s->spin_lock, flags);
comedi_buf_map_put(bm);
}
static void __comedi_buf_alloc(struct comedi_device *dev,
......@@ -80,6 +85,7 @@ static void __comedi_buf_alloc(struct comedi_device *dev,
struct page **pages = NULL;
struct comedi_buf_map *bm;
struct comedi_buf_page *buf;
unsigned long flags;
unsigned i;
if (!IS_ENABLED(CONFIG_HAS_DMA) && s->async_dma_dir != DMA_NONE) {
......@@ -92,8 +98,10 @@ static void __comedi_buf_alloc(struct comedi_device *dev,
if (!bm)
return;
async->buf_map = bm;
kref_init(&bm->refcount);
spin_lock_irqsave(&s->spin_lock, flags);
async->buf_map = bm;
spin_unlock_irqrestore(&s->spin_lock, flags);
bm->dma_dir = s->async_dma_dir;
if (bm->dma_dir != DMA_NONE)
/* Need ref to hardware device to free buffer later. */
......@@ -127,7 +135,9 @@ static void __comedi_buf_alloc(struct comedi_device *dev,
pages[i] = virt_to_page(buf->virt_addr);
}
spin_lock_irqsave(&s->spin_lock, flags);
bm->n_pages = i;
spin_unlock_irqrestore(&s->spin_lock, flags);
/* vmap the prealloc_buf if all the pages were allocated */
if (i == n_pages)
......@@ -150,6 +160,29 @@ int comedi_buf_map_put(struct comedi_buf_map *bm)
return 1;
}
/* returns s->async->buf_map and increments its kref refcount */
struct comedi_buf_map *
comedi_buf_map_from_subdev_get(struct comedi_subdevice *s)
{
struct comedi_async *async = s->async;
struct comedi_buf_map *bm = NULL;
unsigned long flags;
if (!async)
return NULL;
spin_lock_irqsave(&s->spin_lock, flags);
bm = async->buf_map;
/* only want it if buffer pages allocated */
if (bm && bm->n_pages)
comedi_buf_map_get(bm);
else
bm = NULL;
spin_unlock_irqrestore(&s->spin_lock, flags);
return bm;
}
bool comedi_buf_is_mmapped(struct comedi_async *async)
{
struct comedi_buf_map *bm = async->buf_map;
......
......@@ -1926,14 +1926,21 @@ static int comedi_mmap(struct file *file, struct vm_area_struct *vma)
struct comedi_device *dev = file->private_data;
struct comedi_subdevice *s;
struct comedi_async *async;
struct comedi_buf_map *bm;
struct comedi_buf_map *bm = NULL;
unsigned long start = vma->vm_start;
unsigned long size;
int n_pages;
int i;
int retval;
mutex_lock(&dev->mutex);
/*
* 'trylock' avoids circular dependency with current->mm->mmap_sem
* and down-reading &dev->attach_lock should normally succeed without
* contention unless the device is in the process of being attached
* or detached.
*/
if (!down_read_trylock(&dev->attach_lock))
return -EAGAIN;
if (!dev->attached) {
dev_dbg(dev->class_dev, "no driver attached\n");
......@@ -1973,7 +1980,9 @@ static int comedi_mmap(struct file *file, struct vm_area_struct *vma)
}
n_pages = size >> PAGE_SHIFT;
bm = async->buf_map;
/* get reference to current buf map (if any) */
bm = comedi_buf_map_from_subdev_get(s);
if (!bm || n_pages > bm->n_pages) {
retval = -EINVAL;
goto done;
......@@ -1997,7 +2006,8 @@ static int comedi_mmap(struct file *file, struct vm_area_struct *vma)
retval = 0;
done:
mutex_unlock(&dev->mutex);
up_read(&dev->attach_lock);
comedi_buf_map_put(bm); /* put reference to buf map - okay if NULL */
return retval;
}
......
......@@ -19,6 +19,8 @@ void comedi_buf_reset(struct comedi_async *async);
bool comedi_buf_is_mmapped(struct comedi_async *async);
void comedi_buf_map_get(struct comedi_buf_map *bm);
int comedi_buf_map_put(struct comedi_buf_map *bm);
struct comedi_buf_map *comedi_buf_map_from_subdev_get(
struct comedi_subdevice *s);
unsigned int comedi_buf_write_n_allocated(struct comedi_async *async);
void comedi_device_cancel_all(struct comedi_device *dev);
......
......@@ -334,6 +334,7 @@ static int goldfish_audio_probe(struct platform_device *pdev)
return 0;
err_misc_register_failed:
free_irq(data->irq, data);
err_request_irq_failed:
dma_free_coherent(&pdev->dev, COMBINED_BUFFER_SIZE,
data->buffer_virt, data->buffer_phys);
......
gs_fpga-y += gs_fpgaboot.o io.o
obj-$(CONFIG_GS_FPGABOOT) += gs_fpga.o
ccflags-$(CONFIG_GS_FPGA_DEBUG) := -DDEBUG
......@@ -373,7 +373,6 @@ static int __init gs_fpgaboot_init(void)
r = -1;
pr_info("FPGA DOWNLOAD --->\n");
pr_info("built at %s UTC\n", __TIMESTAMP__);
pr_info("FPGA image file name: %s\n", file);
......
config R8187SE
tristate "RealTek RTL8187SE Wireless LAN NIC driver"
depends on PCI && WLAN
depends on m
select WIRELESS_EXT
select WEXT_PRIV
select EEPROM_93CX6
select CRYPTO
---help---
If built as a module, it will be called r8187se.ko.
#ccflags-y += -DCONFIG_IEEE80211_NOWEP=y
#ccflags-y += -std=gnu89
#ccflags-y += -O2
#CC = gcc
ccflags-y := -DSW_ANTE
ccflags-y += -DTX_TRACK
ccflags-y += -DHIGH_POWER
ccflags-y += -DSW_DIG
ccflags-y += -DRATE_ADAPT
#enable it for legacy power save, disable it for leisure power save
ccflags-y += -DENABLE_LPS
#ccflags-y := -mhard-float -DCONFIG_FORCE_HARD_FLOAT=y
r8187se-y := \
r8180_core.o \
r8180_wx.o \
r8180_rtl8225z2.o \
r8185b_init.o \
r8180_dm.o \
ieee80211/dot11d.o \
ieee80211/ieee80211_softmac.o \
ieee80211/ieee80211_rx.o \
ieee80211/ieee80211_tx.o \
ieee80211/ieee80211_wx.o \
ieee80211/ieee80211_module.o \
ieee80211/ieee80211_softmac_wx.o \
ieee80211/ieee80211_crypt.o \
ieee80211/ieee80211_crypt_tkip.o \
ieee80211/ieee80211_crypt_ccmp.o \
ieee80211/ieee80211_crypt_wep.o
obj-$(CONFIG_R8187SE) += r8187se.o
TODO:
- prepare private ieee80211 stack for merge with rtl8192su's version:
- add hwsec_active flag to struct ieee80211_device
- add bHwSec flag to cb_desc structure
- switch to use shared "librtl" instead of private ieee80211 stack
- switch to use LIB80211
- switch to use MAC80211
- use kernel coding style
- checkpatch.pl fixes
- sparse fixes
- integrate with drivers/net/wireless/rtl818x
Please send any patches to Greg Kroah-Hartman <greg@kroah.com>.
#include "dot11d.h"
void Dot11d_Init(struct ieee80211_device *ieee)
{
PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(ieee);
pDot11dInfo->bEnabled = 0;
pDot11dInfo->State = DOT11D_STATE_NONE;
pDot11dInfo->CountryIeLen = 0;
memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1);
memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1);
RESET_CIE_WATCHDOG(ieee);
netdev_info(ieee->dev, "Dot11d_Init()\n");
}
/* Reset to the state as we are just entering a regulatory domain. */
void Dot11d_Reset(struct ieee80211_device *ieee)
{
u32 i;
PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(ieee);
/* Clear old channel map */
memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1);
memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1);
/* Set new channel map */
for (i = 1; i <= 11; i++)
(pDot11dInfo->channel_map)[i] = 1;
for (i = 12; i <= 14; i++)
(pDot11dInfo->channel_map)[i] = 2;
pDot11dInfo->State = DOT11D_STATE_NONE;
pDot11dInfo->CountryIeLen = 0;
RESET_CIE_WATCHDOG(ieee);
}
/*
* Description:
* Update country IE from Beacon or Probe Response and configure PHY for
* operation in the regulatory domain.
*
* TODO:
* Configure Tx power.
*
* Assumption:
* 1. IS_DOT11D_ENABLE() is TRUE.
* 2. Input IE is an valid one.
*/
void Dot11d_UpdateCountryIe(struct ieee80211_device *dev, u8 *pTaddr,
u16 CoutryIeLen, u8 *pCoutryIe)
{
PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
u8 i, j, NumTriples, MaxChnlNum;
u8 index, MaxTxPowerInDbm;
PCHNL_TXPOWER_TRIPLE pTriple;
if ((CoutryIeLen - 3)%3 != 0) {
netdev_info(dev->dev, "Dot11d_UpdateCountryIe(): Invalid country IE, skip it........1\n");
Dot11d_Reset(dev);
return;
}
memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1);
memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1);
MaxChnlNum = 0;
NumTriples = (CoutryIeLen - 3) / 3; /* skip 3-byte country string. */
pTriple = (PCHNL_TXPOWER_TRIPLE)(pCoutryIe + 3);
for (i = 0; i < NumTriples; i++) {
if (MaxChnlNum >= pTriple->FirstChnl) {
/*
* It is not in a monotonically increasing order,
* so stop processing.
*/
netdev_info(dev->dev,
"Dot11d_UpdateCountryIe(): Invalid country IE, skip it........1\n");
Dot11d_Reset(dev);
return;
}
if (MAX_CHANNEL_NUMBER <
(pTriple->FirstChnl + pTriple->NumChnls)) {
/*
* It is not a valid set of channel id,
* so stop processing
*/
netdev_info(dev->dev,
"Dot11d_UpdateCountryIe(): Invalid country IE, skip it........2\n");
Dot11d_Reset(dev);
return;
}
for (j = 0; j < pTriple->NumChnls; j++) {
index = pTriple->FirstChnl + j;
pDot11dInfo->channel_map[index] = 1;
MaxTxPowerInDbm = pTriple->MaxTxPowerInDbm;
pDot11dInfo->MaxTxPwrDbmList[index] = MaxTxPowerInDbm;
MaxChnlNum = pTriple->FirstChnl + j;
}
pTriple = (PCHNL_TXPOWER_TRIPLE)((u8 *)pTriple + 3);
}
#if 1
netdev_info(dev->dev, "Channel List:");
for (i = 1; i <= MAX_CHANNEL_NUMBER; i++)
if (pDot11dInfo->channel_map[i] > 0)
netdev_info(dev->dev, " %d", i);
netdev_info(dev->dev, "\n");
#endif
UPDATE_CIE_SRC(dev, pTaddr);
pDot11dInfo->CountryIeLen = CoutryIeLen;
memcpy(pDot11dInfo->CountryIeBuf, pCoutryIe, CoutryIeLen);
pDot11dInfo->State = DOT11D_STATE_LEARNED;
}
u8 DOT11D_GetMaxTxPwrInDbm(struct ieee80211_device *dev, u8 Channel)
{
PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
u8 MaxTxPwrInDbm = 255;
if (MAX_CHANNEL_NUMBER < Channel) {
netdev_info(dev->dev, "DOT11D_GetMaxTxPwrInDbm(): Invalid Channel\n");
return MaxTxPwrInDbm;
}
if (pDot11dInfo->channel_map[Channel])
MaxTxPwrInDbm = pDot11dInfo->MaxTxPwrDbmList[Channel];
return MaxTxPwrInDbm;
}
void DOT11D_ScanComplete(struct ieee80211_device *dev)
{
PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
switch (pDot11dInfo->State) {
case DOT11D_STATE_LEARNED:
pDot11dInfo->State = DOT11D_STATE_DONE;
break;
case DOT11D_STATE_DONE:
if (GET_CIE_WATCHDOG(dev) == 0) {
/* Reset country IE if previous one is gone. */
Dot11d_Reset(dev);
}
break;
case DOT11D_STATE_NONE:
break;
}
}
int IsLegalChannel(struct ieee80211_device *dev, u8 channel)
{
PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
if (MAX_CHANNEL_NUMBER < channel) {
netdev_info(dev->dev, "IsLegalChannel(): Invalid Channel\n");
return 0;
}
if (pDot11dInfo->channel_map[channel] > 0)
return 1;
return 0;
}
int ToLegalChannel(struct ieee80211_device *dev, u8 channel)
{
PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
u8 default_chn = 0;
u32 i = 0;
for (i = 1; i <= MAX_CHANNEL_NUMBER; i++) {
if (pDot11dInfo->channel_map[i] > 0) {
default_chn = i;
break;
}
}
if (MAX_CHANNEL_NUMBER < channel) {
netdev_info(dev->dev, "IsLegalChannel(): Invalid Channel\n");
return default_chn;
}
if (pDot11dInfo->channel_map[channel] > 0)
return channel;
return default_chn;
}
#ifndef __INC_DOT11D_H
#define __INC_DOT11D_H
#include "ieee80211.h"
/* #define ENABLE_DOT11D */
/* #define DOT11D_MAX_CHNL_NUM 83 */
typedef struct _CHNL_TXPOWER_TRIPLE {
u8 FirstChnl;
u8 NumChnls;
u8 MaxTxPowerInDbm;
} CHNL_TXPOWER_TRIPLE, *PCHNL_TXPOWER_TRIPLE;
typedef enum _DOT11D_STATE {
DOT11D_STATE_NONE = 0,
DOT11D_STATE_LEARNED,
DOT11D_STATE_DONE,
} DOT11D_STATE;
typedef struct _RT_DOT11D_INFO {
/* DECLARE_RT_OBJECT(RT_DOT12D_INFO); */
bool bEnabled; /* dot11MultiDomainCapabilityEnabled */
u16 CountryIeLen; /* > 0 if CountryIeBuf[] contains valid country information element. */
u8 CountryIeBuf[MAX_IE_LEN];
u8 CountryIeSrcAddr[6]; /* Source AP of the country IE. */
u8 CountryIeWatchdog;
u8 channel_map[MAX_CHANNEL_NUMBER+1]; /* !!!Value 0: Invalid, 1: Valid (active scan), 2: Valid (passive scan) */
/* u8 ChnlListLen; // #Bytes valid in ChnlList[]. */
/* u8 ChnlList[DOT11D_MAX_CHNL_NUM]; */
u8 MaxTxPwrDbmList[MAX_CHANNEL_NUMBER+1];
DOT11D_STATE State;
} RT_DOT11D_INFO, *PRT_DOT11D_INFO;
#define eqMacAddr(a, b) (((a)[0] == (b)[0] && (a)[1] == (b)[1] && (a)[2] == (b)[2] && (a)[3] == (b)[3] && (a)[4] == (b)[4] && (a)[5] == (b)[5]) ? 1:0)
#define cpMacAddr(des, src) ((des)[0] = (src)[0], (des)[1] = (src)[1], (des)[2] = (src)[2], (des)[3] = (src)[3], (des)[4] = (src)[4], (des)[5] = (src)[5])
#define GET_DOT11D_INFO(__pIeeeDev) ((PRT_DOT11D_INFO)((__pIeeeDev)->pDot11dInfo))
#define IS_DOT11D_ENABLE(__pIeeeDev) GET_DOT11D_INFO(__pIeeeDev)->bEnabled
#define IS_COUNTRY_IE_VALID(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen > 0)
#define IS_EQUAL_CIE_SRC(__pIeeeDev, __pTa) eqMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa)
#define UPDATE_CIE_SRC(__pIeeeDev, __pTa) cpMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa)
#define IS_COUNTRY_IE_CHANGED(__pIeeeDev, __Ie) \
(((__Ie).Length == 0 || (__Ie).Length != GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen) ? \
FALSE : \
(!memcmp(GET_DOT11D_INFO(__pIeeeDev)->CountryIeBuf, (__Ie).Octet, (__Ie).Length)))
#define CIE_WATCHDOG_TH 1
#define GET_CIE_WATCHDOG(__pIeeeDev) GET_DOT11D_INFO(__pIeeeDev)->CountryIeWatchdog
#define RESET_CIE_WATCHDOG(__pIeeeDev) GET_CIE_WATCHDOG(__pIeeeDev) = 0
#define UPDATE_CIE_WATCHDOG(__pIeeeDev) ++GET_CIE_WATCHDOG(__pIeeeDev)
#define IS_DOT11D_STATE_DONE(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->State == DOT11D_STATE_DONE)
void Dot11d_Init(struct ieee80211_device *dev);
void Dot11d_Reset(struct ieee80211_device *dev);
void Dot11d_UpdateCountryIe(struct ieee80211_device *dev, u8 *pTaddr,
u16 CoutryIeLen, u8 *pCoutryIe);
u8 DOT11D_GetMaxTxPwrInDbm(struct ieee80211_device *dev, u8 Channel);
void DOT11D_ScanComplete(struct ieee80211_device *dev);
int IsLegalChannel(struct ieee80211_device *dev, u8 channel);
int ToLegalChannel(struct ieee80211_device *dev, u8 channel);
#endif /* #ifndef __INC_DOT11D_H */
This diff is collapsed.
/*
* Host AP crypto routines
*
* Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
* Portions Copyright (C) 2004, Intel Corporation <jketreno@linux.intel.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation. See README and COPYING for
* more details.
*
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
//#include <linux/config.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/errno.h>
#include "ieee80211.h"
MODULE_AUTHOR("Jouni Malinen");
MODULE_DESCRIPTION("HostAP crypto");
MODULE_LICENSE("GPL");
struct ieee80211_crypto_alg {
struct list_head list;
struct ieee80211_crypto_ops *ops;
};
struct ieee80211_crypto {
struct list_head algs;
spinlock_t lock;
};
static struct ieee80211_crypto *hcrypt;
void ieee80211_crypt_deinit_entries(struct ieee80211_device *ieee, int force)
{
struct list_head *ptr, *n;
struct ieee80211_crypt_data *entry;
for (ptr = ieee->crypt_deinit_list.next, n = ptr->next;
ptr != &ieee->crypt_deinit_list; ptr = n, n = ptr->next) {
entry = list_entry(ptr, struct ieee80211_crypt_data, list);
if (atomic_read(&entry->refcnt) != 0 && !force)
continue;
list_del(ptr);
if (entry->ops)
entry->ops->deinit(entry->priv);
kfree(entry);
}
}
void ieee80211_crypt_deinit_handler(unsigned long data)
{
struct ieee80211_device *ieee = (struct ieee80211_device *)data;
unsigned long flags;
spin_lock_irqsave(&ieee->lock, flags);
ieee80211_crypt_deinit_entries(ieee, 0);
if (!list_empty(&ieee->crypt_deinit_list)) {
pr_debug("entries remaining in delayed crypt deletion list\n");
ieee->crypt_deinit_timer.expires = jiffies + HZ;
add_timer(&ieee->crypt_deinit_timer);
}
spin_unlock_irqrestore(&ieee->lock, flags);
}
void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee,
struct ieee80211_crypt_data **crypt)
{
struct ieee80211_crypt_data *tmp;
unsigned long flags;
if (*crypt == NULL)
return;