Commit c2ebba9e authored by kaltenbe's avatar kaltenbe

moving openairITS from trunk to extras


git-svn-id: http://svn.eurecom.fr/openair4G/trunk@7778 818b1a75-f10b-46b9-bf7c-635c3b92a50f
parent 426fdbad
#!/bin/sh
## INSTRUCTIONS
## - check the coherence of the OPENAIRITS_DIR and MOD_DIR with YOUR platform
## - configure the module dependencies by running the following command:
## sudo depmod -a
## - install 'iw' by the following command:
## sudo apt-get install iw
## - allow Ubuntu to reply to a PING in Broadcast by the following command:
## echo 0 | sudo tee /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts
## run the following shell
## voila !!
#Path configuration
MOD_DIR=/lib/modules/`uname -r`/kernel
#MOD_DIR=/lib/modules/2.6.32.11+drm33.2.openairinterface.bigphys.rtai/updates
#Modules compilation
cd ${OPENAIRITS_DIR}/mac/DOT11/
sudo make clean
sudo make MAC=1
sudo rm ${MOD_DIR}/compat/compat.ko
sudo rm ${MOD_DIR}/net/wireless/cfg80211.ko
sudo rm ${MOD_DIR}/net/mac80211/mac80211_eurecom.ko
sudo mkdir ${MOD_DIR}/compat
sudo mkdir ${MOD_DIR}/net/wireless
sudo mkdir ${MOD_DIR}/net/mac80211
sudo cp ${OPENAIRITS_DIR}/mac/DOT11/compat/compat.ko ${MOD_DIR}/compat/compat.ko
sudo cp ${OPENAIRITS_DIR}/mac/DOT11/net/wireless/cfg80211.ko ${MOD_DIR}/net/wireless/cfg80211.ko
sudo cp ${OPENAIRITS_DIR}/mac/DOT11/net/mac80211/mac80211_eurecom.ko ${MOD_DIR}/net/mac80211/mac80211_eurecom.ko
cd ${OPENAIRITS_DIR}/phy/DRIVERS/
sudo make clean
sudo make
#Go back to the source directory
cd ${OPENAIRITS_DIR}
## INSTRUCTIONS
## - check the coherence of the OPENAIRITS_DIR and MOD_DIR with YOUR platform
## - configure the module dependencies by running the following command:
## sudo depmod -a
## - install 'iw' by the following command:
## sudo apt-get install iw
## - allow Ubuntu to reply to a PING in Broadcast by the following command:
## echo 0 | sudo tee /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts
## run the following shell
## voila !!
# Interface configuration (interface type, MAC address, IP address, disable ARP)
sudo iw phy phy0 interface add wlan0 type ibss 4addr off
sudo ifconfig wlan0 hw ether 10:11:12:13:14:15
sudo ifconfig wlan0 192.168.1.1 up -arp
# Static ARP table
sudo arp -i wlan0 -s 192.168.1.2 10:21:22:23:24:25
sudo arp -i wlan0 -s 192.168.1.255 FF:FF:FF:FF:FF:FF
#!/bin/sh
# Module loading
sudo depmod -a
sudo modprobe mac80211_eurecom
sudo insmod ${OPENAIRITS_DIR}/phy/DRIVERS/ieee80211p.ko
#!/bin/sh
## INSTRUCTIONS
## - check the coherence of the OPENAIRITS_DIR and MOD_DIR with YOUR platform
## - configure the module dependencies by running the following command:
## sudo depmod -a
## - install 'iw' by the following command:
## sudo apt-get install iw
## - allow Ubuntu to reply to a PING in Broadcast by the following command:
## echo 0 | sudo tee /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts
## run the following shell
## voila !!
#Environment variables
export OPENAIR_HOME=/home/thales/openair4G
export OPENAIR1_DIR=$OPENAIR_HOME/openair1
export OPENAIR2_DIR=$OPENAIR_HOME/openair2
export OPENAIR3_DIR=$OPENAIR_HOME/openair3
export OPENAIR_TARGETS=$OPENAIR_HOME/targets
export OPENAIRITS_DIR=$OPENAIR_HOME/openairITS
drivers
mac80211
bluetooth
include
net
compat
udev
*~
git-describe
compat-release
master-tag
Module.symvers
module.order
.pc
code-metrics.txt
compat_base_tree
compat_base_tree_version
compat_version
.compat_autoconf_compat-*
.config
.config.mk_md5sum.txt
.tmp_versions/
MAINTAINERS
modules
modules.order
This diff is collapsed.
This diff is collapsed.
export KMODDIR?= updates
KMODDIR_ARG:= "INSTALL_MOD_DIR=$(KMODDIR)"
ifneq ($(origin KLIB), undefined)
KMODPATH_ARG:= "INSTALL_MOD_PATH=$(KLIB)"
else
export KLIB:= /lib/modules/$(shell uname -r)
endif
export KLIB_BUILD ?= $(KLIB)/build
export MAKE
DESTDIR?=
ifneq ($(KERNELRELEASE),)
-include $(COMPAT_CONFIG)
include $(COMPAT_CONFIG_CW)
NOSTDINC_FLAGS := -I$(M)/include/ \
-include $(M)/include/linux/compat-2.6.h \
$(CFLAGS)
obj-y := compat/
#obj-$(CONFIG_COMPAT_RFKILL) += net/rfkill/
ifeq ($(BT),)
obj-$(CONFIG_COMPAT_WIRELESS) += net/wireless/ net/mac80211/
#obj-$(CONFIG_COMPAT_WIRELESS_MODULES) += drivers/net/wireless/
#obj-$(CONFIG_COMPAT_NET_USB_MODULES) += drivers/net/usb/
#obj-$(CONFIG_COMPAT_NETWORK_MODULES) += drivers/net/ethernet/atheros/
#obj-$(CONFIG_COMPAT_NETWORK_MODULES) += drivers/net/ethernet/broadcom/
#obj-$(CONFIG_COMPAT_VAR_MODULES) += drivers/ssb/
#obj-$(CONFIG_COMPAT_VAR_MODULES) += drivers/bcma/
#obj-$(CONFIG_COMPAT_VAR_MODULES) += drivers/misc/eeprom/
ifeq ($(CONFIG_STAGING_EXCLUDE_BUILD),)
endif
endif
#obj-$(CONFIG_COMPAT_BLUETOOTH) += net/bluetooth/
#obj-$(CONFIG_COMPAT_BLUETOOTH_MODULES) += drivers/bluetooth/
else
export PWD := $(shell pwd)
# The build will fail if there is any space in PWD.
ifneq (,$(findstring $() ,$(PWD)))
$(error "The path to this compat-wireless directory has spaces in it." \
"Please put it somewhere where there is no space")
endif
export CFLAGS += \
-DCOMPAT_BASE_TREE="\"$(shell cat $(PWD)/compat_base_tree)\"" \
-DCOMPAT_BASE_TREE_VERSION="\"$(shell cat $(PWD)/compat_base_tree_version)\"" \
-DCOMPAT_PROJECT="\"Compat-wireless\"" \
-DCOMPAT_VERSION="\"$(shell cat $(PWD)/compat_version)\""
# These exported as they are used by the scripts
# to check config and compat autoconf
export COMPAT_CONFIG_CW=$(PWD)/config.mk
export COMPAT_CONFIG=$(PWD)/.config
export CONFIG_CHECK=$(PWD)/.config.mk_md5sum.txt
export COMPAT_AUTOCONF=include/linux/compat_autoconf.h
export CREL=$(shell cat $(PWD)/compat_version)
export CREL_PRE:=.compat_autoconf_
export CREL_CHECK:=$(PWD)/$(CREL_PRE)$(CREL)
all: modules
$(COMPAT_CONFIG): ;
modules: $(CREL_CHECK)
$(MAKE) -C $(KLIB_BUILD) M=$(PWD) modules
@touch $@
bt: $(CREL_CHECK)
+@./scripts/check_config.sh
$(MAKE) -C $(KLIB_BUILD) M=$(PWD) BT=TRUE modules
@touch $@
# We use a CREL_CHECK variable which will depend on the environment used to
# build. If the environment requirements change it forces a reconfiguration
# check. This means we force a new reconfiguration check if a the user gets a
# new updates of compat-wireless or when the user updates the $(COMPAT_CONFIG)
# file.
# XXX: add kernel target to the CREL_CHECK mix, this would ensure we also
# reconfigure and build again fresh if we detect a new target kernel is
# being used.
$(CREL_CHECK):
@# Force to regenerate compat autoconf
+@./compat/scripts/gen-compat-config.sh > $(COMPAT_CONFIG)
@rm -f $(CONFIG_CHECK)
+@./scripts/check_config.sh
@md5sum $(COMPAT_CONFIG_CW) > $(CONFIG_CHECK)
@touch $@
btinstall: btuninstall bt-install-modules
bt-install-modules: bt
$(MAKE) -C $(KLIB_BUILD) M=$(PWD) $(KMODDIR_ARG) $(KMODPATH_ARG) BT=TRUE \
modules_install
@/sbin/depmod -ae
@echo
@echo Now run:
@echo
@echo sudo make btunload:
@echo
@echo And then load the needed bluetooth modules. If unsure reboot.
@echo
btuninstall:
@# New location, matches upstream
@rm -rf $(KLIB)/$(KMODDIR)/net/bluetooth/
@rm -rf $(KLIB)/$(KMODDIR)/drivers/bluetooth/
@# Lets only remove the stuff we are sure we are providing
@# on the misc directory.
@/sbin/depmod -ae
@echo
btclean:
$(MAKE) -C /lib/modules/$(shell uname -r)/build M=$(PWD) BT=TRUE clean
@rm -f $(CREL_PRE)*
install: uninstall install-modules install-scripts
install-modules: modules
$(MAKE) -C $(KLIB_BUILD) M=$(PWD) $(KMODDIR_ARG) $(KMODPATH_ARG) \
modules_install
@./scripts/update-initramfs
install-scripts:
@# All the scripts we can use
@mkdir -p $(DESTDIR)/usr/lib/compat-wireless/
@install scripts/modlib.sh $(DESTDIR)/usr/lib/compat-wireless/
@install scripts/madwifi-unload $(DESTDIR)/usr/sbin/
@# This is to allow switching between drivers without blacklisting
@install scripts/athenable $(DESTDIR)/usr/sbin/
@install scripts/b43enable $(DESTDIR)/usr/sbin/
@install scripts/iwl-enable $(DESTDIR)/usr/sbin/
@install scripts/alx-enable $(DESTDIR)/usr/sbin/
@install scripts/athload $(DESTDIR)/usr/sbin/
@install scripts/b43load $(DESTDIR)/usr/sbin/
@install scripts/iwl-load $(DESTDIR)/usr/sbin/
@if [ $(shell modinfo ath_pci > /dev/null 2>&1 && echo 1) ]; then \
echo -n "Note: madwifi detected, we're going to disable it. " ;\
echo "If you would like to enable it later you can run:" ;\
echo " sudo athenable madwifi" ;\
echo ;\
echo Running athenable ath5k...;\
$(DESTDIR)/usr/sbin/athenable ath5k ;\
fi
@if [ $(shell modinfo iwl4965 > /dev/null 2>&1 && echo 1) ]; then \
echo ;\
echo -n "Note: iwl4965 detected, we're going to disable it. " ;\
echo "If you would like to enable it later you can run:" ;\
echo " sudo iwl-load iwl4965" ;\
echo ;\
echo Running iwl-enable iwlagn...;\
$(DESTDIR)/usr/sbin/iwl-enable iwlagn ;\
fi
@if [ $(shell modinfo iwlagn > /dev/null 2>&1 && echo 1) ] \
&& [ $(shell modinfo iwlwifi > /dev/null 2>&1 && echo 1) ]; then \
echo ;\
echo -n "Note: iwlagn detected, we're going to disable it. " ;\
echo "If you would like to enable it later you can run:" ;\
echo " sudo iwl-load iwlagn" ;\
echo ;\
echo Running iwl-enable iwlwifi...;\
$(DESTDIR)/usr/sbin/iwl-enable iwlwifi ;\
fi
@if [ $(shell modinfo atl1c > /dev/null 2>&1 && echo 1) ]; then \
echo ;\
echo -n "Note: atl1c detected, we're going to disable it. " ;\
echo "If you would like to enable it later you can run:" ;\
echo " sudo alx-load atl1c" ;\
echo ;\
echo Running alx-enable alx...;\
$(DESTDIR)/usr/sbin/alx-enable alx;\
fi
@# If on distributions like Mandriva which like to
@# compress their modules this will find out and do
@# it for you. Reason is some old version of modutils
@# won't know mac80211.ko should be used instead of
@# mac80211.ko.gz
@./scripts/compress_modules
@# Mandrake doesn't have a depmod.d/ conf file to prefer
@# the updates/ dir which is what we use so we add one for it
@# (or any other distribution that doens't have this).
@./scripts/check_depmod
@# Udev stuff needed for the new compat_firmware_class.
@./compat/scripts/compat_firmware_install
@/sbin/depmod -a
@echo
@echo Now run:
@echo
@echo sudo make unload to unload all: wireless, bluetooth and ethernet modules
@echo sudo make wlunload to unload wireless modules
@echo sudo make btunload to unload bluetooth modules
@echo
@echo Run sudo modprobe 'driver-name' to load your desired driver.
@echo If unsure reboot.
@echo
uninstall:
@# New location, matches upstream
@rm -rf $(KLIB)/$(KMODDIR)/compat/
@rm -rf $(KLIB)/$(KMODDIR)/net/mac80211/
@rm -rf $(KLIB)/$(KMODDIR)/net/rfkill/
@rm -rf $(KLIB)/$(KMODDIR)/net/wireless/
@rm -rf $(KLIB)/$(KMODDIR)/drivers/ssb/
@rm -rf $(KLIB)/$(KMODDIR)/drivers/net/usb/
@rm -rf $(KLIB)/$(KMODDIR)/drivers/net/wireless/
@rm -rf $(KLIB)/$(KMODDIR)/drivers/staging/
@rm -rf $(KLIB)/$(KMODDIR)/drivers/net/atl*
@# Lets only remove the stuff we are sure we are providing
@# on the misc directory.
@rm -f $(KLIB)/$(KMODDIR)/drivers/misc/eeprom/eeprom_93cx6.ko*
@rm -f $(KLIB)/$(KMODDIR)/drivers/misc/eeprom_93cx6.ko*
@rm -f $(KLIB)/$(KMODDIR)/drivers/net/b44.ko*
@/sbin/depmod -a
@echo
clean:
@if [ -d net -a -d $(KLIB_BUILD) ]; then \
$(MAKE) -C $(KLIB_BUILD) M=$(PWD) clean ;\
fi
@rm -f $(CREL_PRE)*
unload:
@./scripts/unload.sh
btunload:
@./scripts/btunload.sh
wlunload:
@./scripts/wlunload.sh
.PHONY: all clean install uninstall unload btunload wlunload modules bt Makefile
endif
clean-files += Module.symvers Module.markers modules modules.order
clean-files += $(CREL_CHECK) $(CONFIG_CHECK) $(COMPAT_CONFIG)
This diff is collapsed.
compat-wireless code metrics
 829063 - Total upstream lines of code being pulled
 2748 - backport code changes
 2333 - backport code additions
 415 - backport code deletions
 9575 - backport from compat module
 12323 - total backport code
 1.4864 - % of code consists of backport work
Base tree: linux-stable.git
Base tree version: v3.4-rc3
compat-wireless release: compat-wireless-v3.4-rc3-1
ifdef MAC
obj-m += compat.o
#compat-objs :=
#obj-$(CONFIG_COMPAT_FIRMWARE_CLASS) += compat_firmware_class.o
compat-y += main.o
# Compat kernel compatibility code
compat-$(CONFIG_COMPAT_KERNEL_2_6_14) += compat-2.6.14.o
compat-$(CONFIG_COMPAT_KERNEL_2_6_18) += compat-2.6.18.o
compat-$(CONFIG_COMPAT_KERNEL_2_6_19) += compat-2.6.19.o
compat-$(CONFIG_COMPAT_KERNEL_2_6_21) += compat-2.6.21.o
compat-$(CONFIG_COMPAT_KERNEL_2_6_22) += compat-2.6.22.o
compat-$(CONFIG_COMPAT_KERNEL_2_6_23) += compat-2.6.23.o
compat-$(CONFIG_COMPAT_KERNEL_2_6_24) += compat-2.6.24.o
compat-$(CONFIG_COMPAT_KERNEL_2_6_25) += \
compat-2.6.25.o \
pm_qos_params.o
compat-$(CONFIG_COMPAT_KERNEL_2_6_26) += compat-2.6.26.o
compat-$(CONFIG_COMPAT_KERNEL_2_6_27) += compat-2.6.27.o
compat-$(CONFIG_COMPAT_KERNEL_2_6_28) += compat-2.6.28.o
compat-$(CONFIG_COMPAT_KERNEL_2_6_29) += compat-2.6.29.o
compat-$(CONFIG_COMPAT_KERNEL_2_6_32) += compat-2.6.32.o
compat-$(CONFIG_COMPAT_KERNEL_2_6_33) += compat-2.6.33.o
compat-$(CONFIG_COMPAT_KERNEL_2_6_35) += compat-2.6.35.o
compat-$(CONFIG_COMPAT_KERNEL_2_6_36) += compat-2.6.36.o
compat-$(CONFIG_COMPAT_KFIFO) += kfifo.o
compat-$(CONFIG_COMPAT_KERNEL_2_6_37) += compat-2.6.37.o
compat-$(CONFIG_COMPAT_KERNEL_2_6_38) += compat-2.6.38.o
compat-$(CONFIG_COMPAT_KERNEL_2_6_39) += \
compat-2.6.39.o \
kstrtox.o
compat-$(CONFIG_COMPAT_KERNEL_3_0) += compat-3.0.o
compat-$(CONFIG_COMPAT_KERNEL_3_2) += compat-3.2.o
compat-$(CONFIG_COMPAT_KERNEL_3_3) += compat-3.3.o
compat-$(CONFIG_COMPAT_KERNEL_3_5) += compat-3.5.o
compat-$(CONFIG_COMPAT_CORDIC) += cordic.o
compat-$(CONFIG_COMPAT_CRC8) += crc8.o
ifndef CONFIG_64BIT
ifndef CONFIG_GENERIC_ATOMIC64
compat-y += compat_atomic.o
endif
endif
endif
ifdef ALL
obj-m += compat.o
#compat-objs :=
obj-$(CONFIG_COMPAT_FIRMWARE_CLASS) += compat_firmware_class.o
compat-y += main.o
# Compat kernel compatibility code
compat-$(CONFIG_COMPAT_KERNEL_2_6_14) += compat-2.6.14.o
compat-$(CONFIG_COMPAT_KERNEL_2_6_18) += compat-2.6.18.o
compat-$(CONFIG_COMPAT_KERNEL_2_6_19) += compat-2.6.19.o
compat-$(CONFIG_COMPAT_KERNEL_2_6_21) += compat-2.6.21.o
compat-$(CONFIG_COMPAT_KERNEL_2_6_22) += compat-2.6.22.o
compat-$(CONFIG_COMPAT_KERNEL_2_6_23) += compat-2.6.23.o
compat-$(CONFIG_COMPAT_KERNEL_2_6_24) += compat-2.6.24.o
compat-$(CONFIG_COMPAT_KERNEL_2_6_25) += \
compat-2.6.25.o \
pm_qos_params.o
compat-$(CONFIG_COMPAT_KERNEL_2_6_26) += compat-2.6.26.o
compat-$(CONFIG_COMPAT_KERNEL_2_6_27) += compat-2.6.27.o
compat-$(CONFIG_COMPAT_KERNEL_2_6_28) += compat-2.6.28.o
compat-$(CONFIG_COMPAT_KERNEL_2_6_29) += compat-2.6.29.o
compat-$(CONFIG_COMPAT_KERNEL_2_6_32) += compat-2.6.32.o
compat-$(CONFIG_COMPAT_KERNEL_2_6_33) += compat-2.6.33.o
compat-$(CONFIG_COMPAT_KERNEL_2_6_35) += compat-2.6.35.o
compat-$(CONFIG_COMPAT_KERNEL_2_6_36) += compat-2.6.36.o
compat-$(CONFIG_COMPAT_KFIFO) += kfifo.o
compat-$(CONFIG_COMPAT_KERNEL_2_6_37) += compat-2.6.37.o
compat-$(CONFIG_COMPAT_KERNEL_2_6_38) += compat-2.6.38.o
compat-$(CONFIG_COMPAT_KERNEL_2_6_39) += \
compat-2.6.39.o \
kstrtox.o
compat-$(CONFIG_COMPAT_KERNEL_3_0) += compat-3.0.o
compat-$(CONFIG_COMPAT_KERNEL_3_2) += compat-3.2.o
compat-$(CONFIG_COMPAT_KERNEL_3_3) += compat-3.3.o
compat-$(CONFIG_COMPAT_KERNEL_3_5) += compat-3.5.o
compat-$(CONFIG_COMPAT_CORDIC) += cordic.o
compat-$(CONFIG_COMPAT_CRC8) += crc8.o
ifndef CONFIG_64BIT
ifndef CONFIG_GENERIC_ATOMIC64
compat-y += compat_atomic.o
endif
endif
endif
/*
* Copyright 2007 Luis R. Rodriguez <mcgrof@winlab.rutgers.edu>
*
* 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.
*
* Compatibility file for Linux wireless for kernels 2.6.14.
*/
#include <net/compat.h>
/* 2.6.14 compat code goes here */
/*
* Copyright 2007 Luis R. Rodriguez <mcgrof@winlab.rutgers.edu>
*
* 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.
*
* Compatibility file for Linux wireless for kernels 2.6.18.
*/
#include <net/compat.h>
/* 2.6.18 compat code goes here */
/*
* Copyright 2007 Luis R. Rodriguez <mcgrof@winlab.rutgers.edu>
*
* 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.
*
* Compatibility file for Linux wireless for kernels 2.6.19.
*/
#include <net/compat.h>
/* 2.6.19 compat code goes here */
/*
* Copyright 2007 Luis R. Rodriguez <mcgrof@winlab.rutgers.edu>
*
* 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.
*
* Compatibility file for Linux wireless for kernels 2.6.21.
*/
#include <net/compat.h>
/* 2.6.21 compat code goes here */
/*
* Copyright 2007 Luis R. Rodriguez <mcgrof@winlab.rutgers.edu>
*
* 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.
*
* Compatibility file for Linux wireless for kernels 2.6.22.
*/
#include <net/compat.h>
/* 2.6.22 compat code goes here */
/*
* Copyright 2007 Luis R. Rodriguez <mcgrof@winlab.rutgers.edu>
*
* 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.
*
* Compatibility file for Linux wireless for kernels 2.6.23.
*/
#include <net/compat.h>
/* On net/core/dev.c as of 2.6.24 */
int __dev_addr_delete(struct dev_addr_list **list, int *count,
void *addr, int alen, int glbl)
{
struct dev_addr_list *da;
for (; (da = *list) != NULL; list = &da->next) {
if (memcmp(da->da_addr, addr, da->da_addrlen) == 0 &&
alen == da->da_addrlen) {
if (glbl) {
int old_glbl = da->da_gusers;
da->da_gusers = 0;
if (old_glbl == 0)
break;
}
if (--da->da_users)
return 0;
*list = da->next;
kfree(da);
(*count)--;
return 0;
}
}
return -ENOENT;
}
EXPORT_SYMBOL_GPL(__dev_addr_delete);
/* On net/core/dev.c as of 2.6.24. This is not yet used by mac80211 but
* might as well add it */
int __dev_addr_add(struct dev_addr_list **list, int *count,
void *addr, int alen, int glbl)
{
struct dev_addr_list *da;
for (da = *list; da != NULL; da = da->next) {
if (memcmp(da->da_addr, addr, da->da_addrlen) == 0 &&
da->da_addrlen == alen) {
if (glbl) {
int old_glbl = da->da_gusers;
da->da_gusers = 1;
if (old_glbl)
return 0;
}
da->da_users++;
return 0;
}
}
da = kmalloc(sizeof(*da), GFP_ATOMIC);
if (da == NULL)
return -ENOMEM;
memcpy(da->da_addr, addr, alen);
da->da_addrlen = alen;
da->da_users = 1;
da->da_gusers = glbl ? 1 : 0;
da->next = *list;
*list = da;
(*count)++;
return 0;
}
EXPORT_SYMBOL_GPL(__dev_addr_add);
/* Part of net/core/dev_mcast.c as of 2.6.23. This is a slightly different version.
* Since da->da_synced is not part of 2.6.22 we need to take longer route when
* syncing */
/**
* dev_mc_sync - Synchronize device's multicast list to another device
* @to: destination device
* @from: source device
*
* Add newly added addresses to the destination device and release
* addresses that have no users left. The source device must be
* locked by netif_tx_lock_bh.
*
* This function is intended to be called from the dev->set_multicast_list
* function of layered software devices.
*/
int dev_mc_sync(struct net_device *to, struct net_device *from)
{
struct dev_addr_list *da, *next, *da_to;
int err = 0;
netif_tx_lock_bh(to);
da = from->mc_list;
while (da != NULL) {
int synced = 0;
next = da->next;
da_to = to->mc_list;
/* 2.6.22 does not have da->da_synced so lets take the long route */
while (da_to != NULL) {
if (memcmp(da_to->da_addr, da->da_addr, da_to->da_addrlen) == 0 &&
da->da_addrlen == da_to->da_addrlen)
synced = 1;
break;
}
if (!synced) {
err = __dev_addr_add(&to->mc_list, &to->mc_count,
da->da_addr, da->da_addrlen, 0);
if (err < 0)
break;
da->da_users++;
} else if (da->da_users == 1) {
__dev_addr_delete(&to->mc_list, &to->mc_count,
da->da_addr, da->da_addrlen, 0);
__dev_addr_delete(&from->mc_list, &from->mc_count,
da->da_addr, da->da_addrlen, 0);
}
da = next;
}
if (!err)
__dev_set_rx_mode(to);
netif_tx_unlock_bh(to);
return err;
}
EXPORT_SYMBOL_GPL(dev_mc_sync);
/* Part of net/core/dev_mcast.c as of 2.6.23. This is a slighty different version.
* Since da->da_synced is not part of 2.6.22 we need to take longer route when
* unsyncing */
/**
* dev_mc_unsync - Remove synchronized addresses from the destination
* device
* @to: destination device
* @from: source device
*
* Remove all addresses that were added to the destination device by
* dev_mc_sync(). This function is intended to be called from the
* dev->stop function of layered software devices.
*/
void dev_mc_unsync(struct net_device *to, struct net_device *from)
{
struct dev_addr_list *da, *next, *da_to;
netif_tx_lock_bh(from);
netif_tx_lock_bh(to);
da = from->mc_list;
while (da != NULL) {
bool synced = false;
next = da->next;
da_to = to->mc_list;
/* 2.6.22 does not have da->da_synced so lets take the long route */
while (da_to != NULL) {
if (memcmp(da_to->da_addr, da->da_addr, da_to->da_addrlen) == 0 &&
da->da_addrlen == da_to->da_addrlen)
synced = true;
break;
}
if (!synced) {
da = next;
continue;
}
__dev_addr_delete(&to->mc_list, &to->mc_count,
da->da_addr, da->da_addrlen, 0);
__dev_addr_delete(&from->mc_list, &from->mc_count,
da->da_addr, da->da_addrlen, 0);
da = next;
}
__dev_set_rx_mode(to);
netif_tx_unlock_bh(to);
netif_tx_unlock_bh(from);
}
EXPORT_SYMBOL_GPL(dev_mc_unsync);
/* Added as of 2.6.23 on net/core/dev.c. Slightly modifed, no dev->set_rx_mode on
* 2.6.22 so ignore that. */
/*
* Upload unicast and multicast address lists to device and
* configure RX filtering. When the device doesn't support unicast
* filtering it is put in promiscous mode while unicast addresses
* are present.
*/
void __dev_set_rx_mode(struct net_device *dev)
{
/* dev_open will call this function so the list will stay sane. */
if (!(dev->flags&IFF_UP))
return;
if (!netif_device_present(dev))
return;
/* This needs to be ported to 2.6.22 framework */
#if 0
/* Unicast addresses changes may only happen under the rtnl,
* therefore calling __dev_set_promiscuity here is safe.
*/
if (dev->uc_count > 0 && !dev->uc_promisc) {
__dev_set_promiscuity(dev, 1);
dev->uc_promisc = 1;
} else if (dev->uc_count == 0 && dev->uc_promisc) {
__dev_set_promiscuity(dev, -1);
dev->uc_promisc = 0;
}
#endif
if (dev->set_multicast_list)
dev->set_multicast_list(dev);
}
/**
* pci_try_set_mwi - enables memory-write-invalidate PCI transaction
* @dev: the PCI device for which MWI is enabled
*
* Enables the Memory-Write-Invalidate transaction in %PCI_COMMAND.
* Callers are not required to check the return value.
*
* RETURNS: An appropriate -ERRNO error value on error, or zero for success.
*/
int pci_try_set_mwi(struct pci_dev *dev)
{
int rc = 0;
#ifdef HAVE_PCI_SET_MWI
rc = pci_set_mwi(dev);
#endif
return rc;
}
EXPORT_SYMBOL_GPL(pci_try_set_mwi);
#endif
/*
* Copyright 2007 Luis R. Rodriguez <mcgrof@winlab.rutgers.edu>
*
* 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.
*
* Compatibility file for Linux wireless for kernels 2.6.24.
*/
#include <net/compat.h>
#include <net/arp.h>
/*
* We simply won't use it though, just declare it for our wrappers and
* for usage with tons of code that makes mention to it.
*/
struct net init_net;
EXPORT_SYMBOL_GPL(init_net);
/* 2.6.22 and 2.6.23 have eth_header_cache_update defined as extern in include/linux/etherdevice.h
* and actually defined in net/ethernet/eth.c but 2.6.24 exports it. Lets export it here */
/**
* eth_header_cache_update - update cache entry
* @hh: destination cache entry
* @dev: network device
* @haddr: new hardware address
*
* Called by Address Resolution module to notify changes in address.
*/
void eth_header_cache_update(struct hh_cache *hh,
struct net_device *dev,
unsigned char *haddr)
{
memcpy(((u8 *) hh->hh_data) + HH_DATA_OFF(sizeof(struct ethhdr)),
haddr, ETH_ALEN);
}
EXPORT_SYMBOL_GPL(eth_header_cache_update);
/* 2.6.22 and 2.6.23 have eth_header_cache defined as extern in include/linux/etherdevice.h
* and actually defined in net/ethernet/eth.c but 2.6.24 exports it. Lets export it here */
/**
* eth_header_cache - fill cache entry from neighbour
* @neigh: source neighbour
* @hh: destination cache entry
* Create an Ethernet header template from the neighbour.
*/
int eth_header_cache(struct neighbour *neigh, struct hh_cache *hh)
{
__be16 type = hh->hh_type;
struct ethhdr *eth;
const struct net_device *dev = neigh->dev;
eth = (struct ethhdr *)
(((u8 *) hh->hh_data) + (HH_DATA_OFF(sizeof(*eth))));
if (type == htons(ETH_P_802_3))
return -1;
eth->h_proto = type;
memcpy(eth->h_source, dev->dev_addr, ETH_ALEN);
memcpy(eth->h_dest, neigh->ha, ETH_ALEN);
hh->hh_len = ETH_HLEN;
return 0;
}
EXPORT_SYMBOL_GPL(eth_header_cache);
/* 2.6.22 and 2.6.23 have eth_header() defined as extern in include/linux/etherdevice.h
* and actually defined in net/ethernet/eth.c but 2.6.24 exports it. Lets export it here */
/**
* eth_header - create the Ethernet header
* @skb: buffer to alter
* @dev: source device
* @type: Ethernet type field
* @daddr: destination address (NULL leave destination address)
* @saddr: source address (NULL use device source address)
* @len: packet length (<= skb->len)
*
*
* Set the protocol type. For a packet of type ETH_P_802_3 we put the length
* in here instead. It is up to the 802.2 layer to carry protocol information.
*/
int eth_header(struct sk_buff *skb, struct net_device *dev, unsigned short type,
void *daddr, void *saddr, unsigned len)
{
struct ethhdr *eth = (struct ethhdr *)skb_push(skb, ETH_HLEN);
if (type != ETH_P_802_3)
eth->h_proto = htons(type);
else
eth->h_proto = htons(len);
/*
* Set the source hardware address.
*/
if (!saddr)
saddr = dev->dev_addr;
memcpy(eth->h_source, saddr, dev->addr_len);
if (daddr) {
memcpy(eth->h_dest, daddr, dev->addr_len);
return ETH_HLEN;
}
/*
* Anyway, the loopback-device should never use this function...
*/
if (dev->flags & (IFF_LOOPBACK | IFF_NOARP)) {
memset(eth->h_dest, 0, dev->addr_len);
return ETH_HLEN;
}
return -ETH_HLEN;
}
EXPORT_SYMBOL_GPL(eth_header);
/* 2.6.22 and 2.6.23 have eth_rebuild_header defined as extern in include/linux/etherdevice.h
* and actually defined in net/ethernet/eth.c but 2.6.24 exports it. Lets export it here */
/**
* eth_rebuild_header- rebuild the Ethernet MAC header.
* @skb: socket buffer to update
*
* This is called after an ARP or IPV6 ndisc it's resolution on this
* sk_buff. We now let protocol (ARP) fill in the other fields.
*
* This routine CANNOT use cached dst->neigh!
* Really, it is used only when dst->neigh is wrong.
*/
int eth_rebuild_header(struct sk_buff *skb)
{
struct ethhdr *eth = (struct ethhdr *)skb->data;
struct net_device *dev = skb->dev;
switch (eth->h_proto) {
#ifdef CONFIG_INET
case __constant_htons(ETH_P_IP):
return arp_find(eth->h_dest, skb);
#endif
default:
printk(KERN_DEBUG
"%s: unable to resolve type %X addresses.\n",
dev->name, (int)eth->h_proto);
memcpy(eth->h_source, dev->dev_addr, ETH_ALEN);
break;
}
return 0;
}
EXPORT_SYMBOL_GPL(eth_rebuild_header);
/*
* Copyright 2007-2010 Luis R. Rodriguez <mcgrof@winlab.rutgers.edu>
*
* 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.
*
* Compatibility file for Linux wireless for kernels 2.6.25.
*/
#include <linux/miscdevice.h>
/**
* The following things are out of ./lib/vsprintf.c
* The new iwlwifi driver is using them.
*/
/**
* strict_strtoul - convert a string to an unsigned long strictly
* @cp: The string to be converted
* @base: The number base to use
* @res: The converted result value
*
* strict_strtoul converts a string to an unsigned long only if the
* string is really an unsigned long string, any string containing
* any invalid char at the tail will be rejected and -EINVAL is returned,
* only a newline char at the tail is acceptible because people generally
* change a module parameter in the following way:
*
* echo 1024 > /sys/module/e1000/parameters/copybreak
*
* echo will append a newline to the tail.
*
* It returns 0 if conversion is successful and *res is set to the converted
* value, otherwise it returns -EINVAL and *res is set to 0.
*
* simple_strtoul just ignores the successive invalid characters and
* return the converted value of prefix part of the string.
*/
int strict_strtoul(const char *cp, unsigned int base, unsigned long *res);
/**
* strict_strtol - convert a string to a long strictly
* @cp: The string to be converted
* @base: The number base to use
* @res: The converted result value
*
* strict_strtol is similiar to strict_strtoul, but it allows the first
* character of a string is '-'.
*
* It returns 0 if conversion is successful and *res is set to the converted
* value, otherwise it returns -EINVAL and *res is set to 0.
*/
int strict_strtol(const char *cp, unsigned int base, long *res);
#define define_strict_strtoux(type, valtype) \
int strict_strtou##type(const char *cp, unsigned int base, valtype *res)\
{ \
char *tail; \
valtype val; \
size_t len; \
\
*res = 0; \
len = strlen(cp); \
if (len == 0) \
return -EINVAL; \
\
val = simple_strtou##type(cp, &tail, base); \
if ((*tail == '\0') || \
((len == (size_t)(tail - cp) + 1) && (*tail == '\n'))) {\
*res = val; \
return 0; \
} \
\
return -EINVAL; \
} \
#define define_strict_strtox(type, valtype) \
int strict_strto##type(const char *cp, unsigned int base, valtype *res) \
{ \
int ret; \
if (*cp == '-') { \
ret = strict_strtou##type(cp+1, base, res); \
if (!ret) \
*res = -(*res); \
} else \
ret = strict_strtou##type(cp, base, res); \
\
return ret; \
} \
define_strict_strtoux(l, unsigned long)
define_strict_strtox(l, long)
EXPORT_SYMBOL_GPL(strict_strtoul);
EXPORT_SYMBOL_GPL(strict_strtol);
/*
* Copyright 2007-2010 Luis R. Rodriguez <mcgrof@winlab.rutgers.edu>
*
* 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.
*
* Compatibility file for Linux wireless for kernels 2.6.26.
*
* Copyright holders from ported work:
*
* Copyright (c) 2002-2003 Patrick Mochel <mochel@osdl.org>
* Copyright (c) 2006-2007 Greg Kroah-Hartman <greg@kroah.com>
* Copyright (c) 2006-2007 Novell Inc.
*/
#include <net/compat.h>
/* 2.6.24 does not have the struct kobject with a name */
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,25))
/**
* kobject_set_name_vargs - Set the name of an kobject
* @kobj: struct kobject to set the name of
* @fmt: format string used to build the name
* @vargs: vargs to format the string.
*/
static
int kobject_set_name_vargs(struct kobject *kobj, const char *fmt,
va_list vargs)
{
const char *old_name = kobj->name;
char *s;
if (kobj->name && !fmt)
return 0;
kobj->name = kvasprintf(GFP_KERNEL, fmt, vargs);
if (!kobj->name)
return -ENOMEM;
/* ewww... some of these buggers have '/' in the name ... */
while ((s = strchr(kobj->name, '/')))
s[0] = '!';
kfree(old_name);
return 0;
}
#else
static
int kobject_set_name_vargs(struct kobject *kobj, const char *fmt,
va_list vargs)
{
struct device *dev;
unsigned int len;
va_list aq;
dev = container_of(kobj, struct device, kobj);
va_copy(aq, vargs);
len = vsnprintf(NULL, 0, fmt, aq);
va_end(aq);
len = len < BUS_ID_SIZE ? (len + 1) : BUS_ID_SIZE;
vsnprintf(dev->bus_id, len, fmt, vargs);
return 0;
}
#endif
/**
* dev_set_name - set a device name
* @dev: device
* @fmt: format string for the device's name
*/
int dev_set_name(struct device *dev, const char *fmt, ...)
{
va_list vargs;
int err;
va_start(vargs, fmt);
err = kobject_set_name_vargs(&dev->kobj, fmt, vargs);
va_end(vargs);
return err;
}
EXPORT_SYMBOL_GPL(dev_set_name);
/*
* Copyright 2007 Luis R. Rodriguez <mcgrof@winlab.rutgers.edu>
*
* 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.
*
* Compatibility file for Linux wireless for kernels 2.6.27
*/
#include <linux/compat.h>
#include <linux/pci.h>
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24))
#include <linux/mmc/sdio.h>
#include <linux/mmc/sdio_func.h>
#include <linux/mmc/card.h>
#include <linux/mmc/host.h>
#endif
/* rfkill notification chain */
#define RFKILL_STATE_CHANGED 0x0001 /* state of a normal rfkill
switch has changed */
/*
* e5899e1b7d73e67de758a32174a859cc2586c0b9 made pci_pme_capable() external,
* it was defined internally, some drivers want access to this information.
*
* Unfortunately the old kernels do not have ->pm_cap or ->pme_support so
* we have to call the PCI routines directly.
*/
/**
* pci_pme_capable - check the capability of PCI device to generate PME#
* @dev: PCI device to handle.
* @state: PCI state from which device will issue PME#.
*
* This is the backport code for older kernels for compat-wireless, we read stuff
* from the initialization stuff from pci_pm_init().
*/
bool pci_pme_capable(struct pci_dev *dev, pci_power_t state)
{
int pm;
u16 pmc = 0;
u16 pme_support; /* as from the pci dev */
/* find PCI PM capability in list */
pm = pci_find_capability(dev, PCI_CAP_ID_PM);
if (!pm)
return false;
if ((pmc & PCI_PM_CAP_VER_MASK) > 3) {
dev_err(&dev->dev, "unsupported PM cap regs version (%u)\n",
pmc & PCI_PM_CAP_VER_MASK);
return false;
}
pmc &= PCI_PM_CAP_PME_MASK;
if (!pmc)
return false;
pme_support = pmc >> PCI_PM_CAP_PME_SHIFT;
/* Check device's ability to generate PME# */
return !!(pme_support & (1 << state));
}
EXPORT_SYMBOL_GPL(pci_pme_capable);
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24))
/**
* mmc_align_data_size - pads a transfer size to a more optimal value
* @card: the MMC card associated with the data transfer
* @sz: original transfer size
*
* Pads the original data size with a number of extra bytes in
* order to avoid controller bugs and/or performance hits
* (e.g. some controllers revert to PIO for certain sizes).
*
* Returns the improved size, which might be unmodified.
*
* Note that this function is only relevant when issuing a
* single scatter gather entry.
*/
unsigned int mmc_align_data_size(struct mmc_card *card, unsigned int sz)
{
/*
* FIXME: We don't have a system for the controller to tell
* the core about its problems yet, so for now we just 32-bit
* align the size.
*/
sz = ((sz + 3) / 4) * 4;
return sz;
}
EXPORT_SYMBOL_GPL(mmc_align_data_size);
/*
* Calculate the maximum byte mode transfer size
*/
static inline unsigned int sdio_max_byte_size(struct sdio_func *func)
{
unsigned int mval = (unsigned int) min(func->card->host->max_seg_size,
func->card->host->max_blk_size);
mval = min(mval, func->max_blksize);
return min(mval, 512u); /* maximum size for byte mode */
}
/**
* sdio_align_size - pads a transfer size to a more optimal value
* @func: SDIO function
* @sz: original transfer size
*
* Pads the original data size with a number of extra bytes in
* order to avoid controller bugs and/or performance hits
* (e.g. some controllers revert to PIO for certain sizes).
*
* If possible, it will also adjust the size so that it can be
* handled in just a single request.
*
* Returns the improved size, which might be unmodified.
*/
unsigned int sdio_align_size(struct sdio_func *func, unsigned int sz)
{
unsigned int orig_sz;
unsigned int blk_sz, byte_sz;
unsigned chunk_sz;
orig_sz = sz;
/*
* Do a first check with the controller, in case it
* wants to increase the size up to a point where it
* might need more than one block.
*/
sz = mmc_align_data_size(func->card, sz);
/*
* If we can still do this with just a byte transfer, then
* we're done.
*/
if (sz <= sdio_max_byte_size(func))
return sz;
if (func->card->cccr.multi_block) {
/*
* Check if the transfer is already block aligned
*/
if ((sz % func->cur_blksize) == 0)
return sz;
/*
* Realign it so that it can be done with one request,
* and recheck if the controller still likes it.
*/
blk_sz = ((sz + func->cur_blksize - 1) /
func->cur_blksize) * func->cur_blksize;
blk_sz = mmc_align_data_size(func->card, blk_sz);
/*
* This value is only good if it is still just
* one request.
*/
if ((blk_sz % func->cur_blksize) == 0)
return blk_sz;
/*
* We failed to do one request, but at least try to
* pad the remainder properly.
*/
byte_sz = mmc_align_data_size(func->card,
sz % func->cur_blksize);
if (byte_sz <= sdio_max_byte_size(func)) {
blk_sz = sz / func->cur_blksize;
return blk_sz * func->cur_blksize + byte_sz;
}
} else {
/*
* We need multiple requests, so first check that the
* controller can handle the chunk size;
*/
chunk_sz = mmc_align_data_size(func->card,
sdio_max_byte_size(func));
if (chunk_sz == sdio_max_byte_size(func)) {
/*
* Fix up the size of the remainder (if any)
*/
byte_sz = orig_sz % chunk_sz;
if (byte_sz) {
byte_sz = mmc_align_data_size(func->card,
byte_sz);
}
return (orig_sz / chunk_sz) * chunk_sz + byte_sz;
}
}
/*
* The controller is simply incapable of transferring the size
* we want in decent manner, so just return the original size.
*/
return orig_sz;
}
EXPORT_SYMBOL_GPL(sdio_align_size);
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24) */
#ifdef CONFIG_DEBUG_FS
/*
* Backport of debugfs_remove_recursive() without using the internals globals
* which are used by the kernel's version with:
* simple_release_fs(&debugfs_mount, &debugfs_mount_count);
*/
void debugfs_remove_recursive(struct dentry *dentry)
{
struct dentry *last = NULL;
/* Sanity checks */
if (!dentry || !dentry->d_parent || !dentry->d_parent->d_inode)
return;
while (dentry != last) {
struct dentry *child = dentry;
/* Find a child without children */
while (!list_empty(&child->d_subdirs))
child = list_entry(child->d_subdirs.next,
struct dentry,
d_u.d_child);
/* Bail out if we already tried to remove that entry */
if (child == last)
return;
last = child;
debugfs_remove(child);
}
}
EXPORT_SYMBOL_GPL(debugfs_remove_recursive);
#endif /* CONFIG_DEBUG_FS */
This diff is collapsed.
/*
* Copyright 2007-2010 Luis R. Rodriguez <mcgrof@winlab.rutgers.edu>
*
* 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.
*
* Compatibility file for Linux wireless for kernels 2.6.29.
*/
#include <linux/compat.h>
#include <linux/usb.h>
#include <linux/etherdevice.h>
/*
* If you don't see your net_device_ops implemented on
* netdev_attach_ops() then you are shit out of luck and
* you must do the nasty ifdef magic, unless you figure
* out a way to squeze your hacks into this routine :)
*/
void netdev_attach_ops(struct net_device *dev,
const struct net_device_ops *ops)
{
dev->open = ops->ndo_open;
dev->init = ops->ndo_init;
dev->stop = ops->ndo_stop;
dev->hard_start_xmit = ops->ndo_start_xmit;
dev->change_rx_flags = ops->ndo_change_rx_flags;
dev->set_multicast_list = ops->ndo_set_multicast_list;
dev->validate_addr = ops->ndo_validate_addr;
dev->do_ioctl = ops->ndo_do_ioctl;
dev->set_config = ops->ndo_set_config;
dev->change_mtu = ops->ndo_change_mtu;
dev->set_mac_address = ops->ndo_set_mac_address;
dev->tx_timeout = ops->ndo_tx_timeout;
if (ops->ndo_get_stats)
dev->get_stats = ops->ndo_get_stats;
dev->vlan_rx_register = ops->ndo_vlan_rx_register;
dev->vlan_rx_add_vid = ops->ndo_vlan_rx_add_vid;
dev->vlan_rx_kill_vid = ops->ndo_vlan_rx_kill_vid;
#ifdef CONFIG_NET_POLL_CONTROLLER
dev->poll_controller = ops->ndo_poll_controller;
#endif
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))
dev->select_queue = ops->ndo_select_queue;
#endif
}
EXPORT_SYMBOL_GPL(netdev_attach_ops);
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23))
#if defined(CONFIG_USB) || defined(CONFIG_USB_MODULE)
/**
* usb_unpoison_anchored_urbs - let an anchor be used successfully again
* @anchor: anchor the requests are bound to
*
* Reverses the effect of usb_poison_anchored_urbs
* the anchor can be used normally after it returns
*/
void usb_unpoison_anchored_urbs(struct usb_anchor *anchor)
{
unsigned long flags;
struct urb *lazarus;
spin_lock_irqsave(&anchor->lock, flags);
list_for_each_entry(lazarus, &anchor->urb_list, anchor_list) {
usb_unpoison_urb(lazarus);
}
//anchor->poisoned = 0; /* XXX: cannot backport */
spin_unlock_irqrestore(&anchor->lock, flags);
}
EXPORT_SYMBOL_GPL(usb_unpoison_anchored_urbs);
#endif /* CONFIG_USB */
#endif
/**
* eth_mac_addr - set new Ethernet hardware address
* @dev: network device
* @p: socket address
* Change hardware address of device.
*
* This doesn't change hardware matching, so needs to be overridden
* for most real devices.
*/
int eth_mac_addr(struct net_device *dev, void *p)
{
struct sockaddr *addr = p;
if (netif_running(dev))
return -EBUSY;
if (!is_valid_ether_addr(addr->sa_data))
return -EADDRNOTAVAIL;
memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
return 0;
}
EXPORT_SYMBOL_GPL(eth_mac_addr);
/**
* eth_change_mtu - set new MTU size
* @dev: network device
* @new_mtu: new Maximum Transfer Unit
*
* Allow changing MTU size. Needs to be overridden for devices
* supporting jumbo frames.
*/
int eth_change_mtu(struct net_device *dev, int new_mtu)
{
if (new_mtu < 68 || new_mtu > ETH_DATA_LEN)
return -EINVAL;
dev->mtu = new_mtu;
return 0;
}
EXPORT_SYMBOL_GPL(eth_change_mtu);
int eth_validate_addr(struct net_device *dev)
{
if (!is_valid_ether_addr(dev->dev_addr))
return -EADDRNOTAVAIL;
return 0;
}
EXPORT_SYMBOL_GPL(eth_validate_addr);
/* Source: net/ethernet/eth.c */
#define NETREG_DUMMY 5
/**
* init_dummy_netdev - init a dummy network device for NAPI
* @dev: device to init
*
* This takes a network device structure and initialize the minimum
* amount of fields so it can be used to schedule NAPI polls without
* registering a full blown interface. This is to be used by drivers
* that need to tie several hardware interfaces to a single NAPI
* poll scheduler due to HW limitations.
*/
int init_dummy_netdev(struct net_device *dev)
{
/* Clear everything. Note we don't initialize spinlocks
* are they aren't supposed to be taken by any of the
* NAPI code and this dummy netdev is supposed to be
* only ever used for NAPI polls
*/
memset(dev, 0, sizeof(struct net_device));
/* make sure we BUG if trying to hit standard
* register/unregister code path
*/
dev->reg_state = NETREG_DUMMY;
/* initialize the ref count */
atomic_set(&dev->refcnt, 1);
#ifdef CONFIG_NETPOLL
/* NAPI wants this */
INIT_LIST_HEAD(&dev->napi_list);
#endif
/* a dummy interface is started by default */
set_bit(__LINK_STATE_PRESENT, &dev->state);
set_bit(__LINK_STATE_START, &dev->state);
return 0;
}
EXPORT_SYMBOL_GPL(init_dummy_netdev);
/* Source: net/core/dev.c */
/*
* Copyright 2007 Luis R. Rodriguez <mcgrof@winlab.rutgers.edu>
*
* 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.
*
* Compatibility file for Linux wireless for kernels 2.6.32.
*/
#include <linux/compat.h>
#include <linux/netdevice.h>
int __dev_addr_add(struct dev_addr_list **list, int *count,
void *addr, int alen, int glbl)
{
struct dev_addr_list *da;
for (da = *list; da != NULL; da = da->next) {
if (memcmp(da->da_addr, addr, da->da_addrlen) == 0 &&
da->da_addrlen == alen) {
if (glbl) {
int old_glbl = da->da_gusers;
da->da_gusers = 1;
if (old_glbl)
return 0;
}
da->da_users++;
return 0;
}
}
da = kzalloc(sizeof(*da), GFP_ATOMIC);
if (da == NULL)
return -ENOMEM;
memcpy(da->da_addr, addr, alen);
da->da_addrlen = alen;
da->da_users = 1;
da->da_gusers = glbl ? 1 : 0;
da->next = *list;
*list = da;
(*count)++;
return 0;
}
int __dev_addr_delete(struct dev_addr_list **list, int *count,
void *addr, int alen, int glbl)
{
struct dev_addr_list *da;
for (; (da = *list) != NULL; list = &da->next) {
if (memcmp(da->da_addr, addr, da->da_addrlen) == 0 &&
alen == da->da_addrlen) {
if (glbl) {
int old_glbl = da->da_gusers;
da->da_gusers = 0;
if (old_glbl == 0)
break;
}
if (--da->da_users)
return 0;
*list = da->next;
kfree(da);
(*count)--;
return 0;
}
}
return -ENOENT;
}
int __dev_addr_sync(struct dev_addr_list **to, int *to_count,
struct dev_addr_list **from, int *from_count)
{
struct dev_addr_list *da, *next;
int err = 0;
da = *from;
while (da != NULL) {
next = da->next;
if (!da->da_synced) {
err = __dev_addr_add(to, to_count,
da->da_addr, da->da_addrlen, 0);
if (err < 0)
break;
da->da_synced = 1;
da->da_users++;
} else if (da->da_users == 1) {
__dev_addr_delete(to, to_count,
da->da_addr, da->da_addrlen, 0);
__dev_addr_delete(from, from_count,
da->da_addr, da->da_addrlen, 0);
}
da = next;
}
return err;
}
EXPORT_SYMBOL_GPL(__dev_addr_sync);
void __dev_addr_unsync(struct dev_addr_list **to, int *to_count,
struct dev_addr_list **from, int *from_count)
{
struct dev_addr_list *da, *next;
da = *from;
while (da != NULL) {
next = da->next;
if (da->da_synced) {
__dev_addr_delete(to, to_count,
da->da_addr, da->da_addrlen, 0);
da->da_synced = 0;
__dev_addr_delete(from, from_count,
da->da_addr, da->da_addrlen, 0);
}
da = next;
}
}
EXPORT_SYMBOL_GPL(__dev_addr_unsync);
/*
* Nonzero if YEAR is a leap year (every 4 years,
* except every 100th isn't, and every 400th is).
*/
static int __isleap(long year)
{
return (year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0);
}
/* do a mathdiv for long type */
static long math_div(long a, long b)
{
return a / b - (a % b < 0);
}
/* How many leap years between y1 and y2, y1 must less or equal to y2 */
static long leaps_between(long y1, long y2)
{
long leaps1 = math_div(y1 - 1, 4) - math_div(y1 - 1, 100)
+ math_div(y1 - 1, 400);
long leaps2 = math_div(y2 - 1, 4) - math_div(y2 - 1, 100)
+ math_div(y2 - 1, 400);
return leaps2 - leaps1;
}
/* How many days come before each month (0-12). */
static const unsigned short __mon_yday[2][13] = {
/* Normal years. */
{0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365},
/* Leap years. */
{0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366}
};
#define SECS_PER_HOUR (60 * 60)
#define SECS_PER_DAY (SECS_PER_HOUR * 24)
/**
* time_to_tm - converts the calendar time to local broken-down time
*
* @totalsecs the number of seconds elapsed since 00:00:00 on January 1, 1970,
* Coordinated Universal Time (UTC).
* @offset offset seconds adding to totalsecs.
* @result pointer to struct tm variable to receive broken-down time
*/
void time_to_tm(time_t totalsecs, int offset, struct tm *result)
{
long days, rem, y;
const unsigned short *ip;
days = totalsecs / SECS_PER_DAY;
rem = totalsecs % SECS_PER_DAY;
rem += offset;
while (rem < 0) {
rem += SECS_PER_DAY;
--days;
}
while (rem >= SECS_PER_DAY) {
rem -= SECS_PER_DAY;
++days;
}
result->tm_hour = rem / SECS_PER_HOUR;
rem %= SECS_PER_HOUR;
result->tm_min = rem / 60;
result->tm_sec = rem % 60;
/* January 1, 1970 was a Thursday. */
result->tm_wday = (4 + days) % 7;
if (result->tm_wday < 0)
result->tm_wday += 7;
y = 1970;
while (days < 0 || days >= (__isleap(y) ? 366 : 365)) {
/* Guess a corrected year, assuming 365 days per year. */
long yg = y + math_div(days, 365);
/* Adjust DAYS and Y to match the guessed year. */
days -= (yg - y) * 365 + leaps_between(y, yg);
y = yg;
}
result->tm_year = y - 1900;
result->tm_yday = days;
ip = __mon_yday[__isleap(y)];
for (y = 11; days < ip[y]; y--)
continue;
days -= ip[y];
result->tm_mon = y;
result->tm_mday = days + 1;
}
EXPORT_SYMBOL_GPL(time_to_tm);
/* source: kernel/time/timeconv.c*/
/*
* Copyright 2009 Hauke Mehrtens <hauke@hauke-m.de>
*
* 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.
*
* Compatibility file for Linux wireless for kernels 2.6.33.
*/
#include <linux/compat.h>
#include <linux/autoconf.h>
#if defined(CONFIG_PCCARD) || defined(CONFIG_PCCARD_MODULE)
/**
* pccard_loop_tuple() - loop over tuples in the CIS
* @s: the struct pcmcia_socket where the card is inserted
* @function: the device function we loop for
* @code: which CIS code shall we look for?
* @parse: buffer where the tuple shall be parsed (or NULL, if no parse)
* @priv_data: private data to be passed to the loop_tuple function.
* @loop_tuple: function to call for each CIS entry of type @function. IT
* gets passed the raw tuple, the paresed tuple (if @parse is
* set) and @priv_data.
*
* pccard_loop_tuple() loops over all CIS entries of type @function, and
* calls the @loop_tuple function for each entry. If the call to @loop_tuple
* returns 0, the loop exits. Returns 0 on success or errorcode otherwise.
*/
int pccard_loop_tuple(struct pcmcia_socket *s, unsigned int function,
cisdata_t code, cisparse_t *parse, void *priv_data,
int (*loop_tuple) (tuple_t *tuple,
cisparse_t *parse,
void *priv_data))
{
tuple_t tuple;
cisdata_t *buf;
int ret;
buf = kzalloc(256, GFP_KERNEL);
if (buf == NULL) {
dev_printk(KERN_WARNING, &s->dev, "no memory to read tuple\n");
return -ENOMEM;
}
tuple.TupleData = buf;
tuple.TupleDataMax = 255;
tuple.TupleOffset = 0;
tuple.DesiredTuple = code;
tuple.Attributes = 0;
ret = pccard_get_first_tuple(s, function, &tuple);
while (!ret) {
if (pccard_get_tuple_data(s, &tuple))
goto next_entry;
if (parse)
if (pcmcia_parse_tuple(&tuple, parse))
goto next_entry;
ret = loop_tuple(&tuple, parse, priv_data);
if (!ret)
break;
next_entry:
ret = pccard_get_next_tuple(s, function, &tuple);
}
kfree(buf);
return ret;
}
EXPORT_SYMBOL_GPL(pccard_loop_tuple);
/* Source: drivers/pcmcia/cistpl.c */
#if defined(CONFIG_PCMCIA) || defined(CONFIG_PCMCIA_MODULE)
struct pcmcia_loop_mem {
struct pcmcia_device *p_dev;
void *priv_data;
int (*loop_tuple) (struct pcmcia_device *p_dev,
tuple_t *tuple,
void *priv_data);
};
/**
* pcmcia_do_loop_tuple() - internal helper for pcmcia_loop_config()
*
* pcmcia_do_loop_tuple() is the internal callback for the call from
* pcmcia_loop_tuple() to pccard_loop_tuple(). Data is transferred
* by a struct pcmcia_cfg_mem.
*/
static int pcmcia_do_loop_tuple(tuple_t *tuple, cisparse_t *parse, void *priv)
{
struct pcmcia_loop_mem *loop = priv;
return loop->loop_tuple(loop->p_dev, tuple, loop->priv_data);
};
/**
* pcmcia_loop_tuple() - loop over tuples in the CIS
* @p_dev: the struct pcmcia_device which we need to loop for.
* @code: which CIS code shall we look for?
* @priv_data: private data to be passed to the loop_tuple function.
* @loop_tuple: function to call for each CIS entry of type @function. IT
* gets passed the raw tuple and @priv_data.
*
* pcmcia_loop_tuple() loops over all CIS entries of type @function, and
* calls the @loop_tuple function for each entry. If the call to @loop_tuple
* returns 0, the loop exits. Returns 0 on success or errorcode otherwise.
*/
int pcmcia_loop_tuple(struct pcmcia_device *p_dev, cisdata_t code,
int (*loop_tuple) (struct pcmcia_device *p_dev,
tuple_t *tuple,
void *priv_data),
void *priv_data)
{
struct pcmcia_loop_mem loop = {
.p_dev = p_dev,
.loop_tuple = loop_tuple,
.priv_data = priv_data};
return pccard_loop_tuple(p_dev->socket, p_dev->func, code, NULL,
&loop, pcmcia_do_loop_tuple);
}
EXPORT_SYMBOL_GPL(pcmcia_loop_tuple);
/* Source: drivers/pcmcia/pcmcia_resource.c */
#endif /* CONFIG_PCMCIA */
#endif /* CONFIG_PCCARD */
/*
* Copyright 2010 Kshitij Kulshreshtha <kkhere.geo@gmail.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.
*
* Compatibility file for Linux wireless for kernels 2.6.35.
*/
#include <linux/compat.h>
#include <linux/ctype.h>
/**
* hex_to_bin - convert a hex digit to its real value
* @ch: ascii character represents hex digit
*
* hex_to_bin() converts one hex digit to its actual value or -1 in case of bad
* input.
*/
int compat_hex_to_bin(char ch)
{
if ((ch >= '0') && (ch <= '9'))
return ch - '0';
ch = tolower(ch);
if ((ch >= 'a') && (ch <= 'f'))
return ch - 'a' + 10;
return -1;
}
EXPORT_SYMBOL_GPL(compat_hex_to_bin);
/**
* noop_llseek - No Operation Performed llseek implementation
* @file: file structure to seek on
* @offset: file offset to seek to
* @origin: type of seek
*
* This is an implementation of ->llseek useable for the rare special case when
* userspace expects the seek to succeed but the (device) file is actually not
* able to perform the seek. In this case you use noop_llseek() instead of
* falling back to the default implementation of ->llseek.
*/
loff_t noop_llseek(struct file *file, loff_t offset, int origin)
{
return file->f_pos;
}
EXPORT_SYMBOL_GPL(noop_llseek);
/*
* Copyright 2010 Hauke Mehrtens <hauke@hauke-m.de>
*
* 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.
*
* Compatibility file for Linux wireless for kernels 2.6.36.
*/
#include <linux/compat.h>
#include <linux/usb.h>
#ifdef CONFIG_COMPAT_USB_URB_THREAD_FIX
/* Callers must hold anchor->lock */
static void __usb_unanchor_urb(struct urb *urb, struct usb_anchor *anchor)
{
urb->anchor = NULL;
list_del(&urb->anchor_list);
usb_put_urb(urb);
if (list_empty(&anchor->urb_list))
wake_up(&anchor->wait);
}
/**
* usb_unlink_anchored_urbs - asynchronously cancel transfer requests en masse
* @anchor: anchor the requests are bound to
*
* this allows all outstanding URBs to be unlinked starting
* from the back of the queue. This function is asynchronous.
* The unlinking is just tiggered. It may happen after this
* function has returned.
*
* This routine should not be called by a driver after its disconnect
* method has returned.
*/
void compat_usb_unlink_anchored_urbs(struct usb_anchor *anchor)
{
struct urb *victim;
while ((victim = usb_get_from_anchor(anchor)) != NULL) {
usb_unlink_urb(victim);
usb_put_urb(victim);
}
}
EXPORT_SYMBOL_GPL(compat_usb_unlink_anchored_urbs);
/**
* usb_get_from_anchor - get an anchor's oldest urb
* @anchor: the anchor whose urb you want
*
* this will take the oldest urb from an anchor,
* unanchor and return it
*/
struct urb *compat_usb_get_from_anchor(struct usb_anchor *anchor)
{
struct urb *victim;
unsigned long flags;
spin_lock_irqsave(&anchor->lock, flags);
if (!list_empty(&anchor->urb_list)) {
victim = list_entry(anchor->urb_list.next, struct urb,
anchor_list);
usb_get_urb(victim);
__usb_unanchor_urb(victim, anchor);
} else {
victim = NULL;
}
spin_unlock_irqrestore(&anchor->lock, flags);
return victim;
}
EXPORT_SYMBOL_GPL(compat_usb_get_from_anchor);
/**
* usb_scuttle_anchored_urbs - unanchor all an anchor's urbs
* @anchor: the anchor whose urbs you want to unanchor
*
* use this to get rid of all an anchor's urbs
*/
void compat_usb_scuttle_anchored_urbs(struct usb_anchor *anchor)
{
struct urb *victim;
unsigned long flags;
spin_lock_irqsave(&anchor->lock, flags);
while (!list_empty(&anchor->urb_list)) {
victim = list_entry(anchor->urb_list.prev, struct urb,
anchor_list);
__usb_unanchor_urb(victim, anchor);
}
spin_unlock_irqrestore(&anchor->lock, flags);
}
EXPORT_SYMBOL_GPL(compat_usb_scuttle_anchored_urbs);
#endif /* CONFIG_COMPAT_USB_URB_THREAD_FIX */
struct workqueue_struct *system_wq __read_mostly;
struct workqueue_struct *system_long_wq __read_mostly;
struct workqueue_struct *system_nrt_wq __read_mostly;
EXPORT_SYMBOL_GPL(system_wq);
EXPORT_SYMBOL_GPL(system_long_wq);
EXPORT_SYMBOL_GPL(system_nrt_wq);
int compat_schedule_work(struct work_struct *work)
{
return queue_work(system_wq, work);
}
EXPORT_SYMBOL_GPL(compat_schedule_work);
int compat_schedule_work_on(int cpu, struct work_struct *work)
{
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))
return queue_work_on(cpu, system_wq, work);
#else
return queue_work(system_wq, work);
#endif
}
EXPORT_SYMBOL_GPL(compat_schedule_work_on);
int compat_schedule_delayed_work(struct delayed_work *dwork,
unsigned long delay)
{
return queue_delayed_work(system_wq, dwork, delay);
}
EXPORT_SYMBOL_GPL(compat_schedule_delayed_work);
int compat_schedule_delayed_work_on(int cpu,
struct delayed_work *dwork,
unsigned long delay)
{
return queue_delayed_work_on(cpu, system_wq, dwork, delay);
}
EXPORT_SYMBOL_GPL(compat_schedule_delayed_work_on);
void compat_flush_scheduled_work(void)
{
/*
* It is debatable which one we should prioritize first, lets
* go with the old kernel's one first for now (keventd_wq) and
* if think its reasonable later we can flip this around.
*/
flush_workqueue(system_wq);
flush_scheduled_work();
}
EXPORT_SYMBOL_GPL(compat_flush_scheduled_work);
/**
* work_busy - test whether a work is currently pending or running
* @work: the work to be tested
*
* Test whether @work is currently pending or running. There is no
* synchronization around this function and the test result is
* unreliable and only useful as advisory hints or for debugging.
* Especially for reentrant wqs, the pending state might hide the
* running state.
*
* RETURNS:
* OR'd bitmask of WORK_BUSY_* bits.
*/
unsigned int work_busy(struct work_struct *work)
{
unsigned int ret = 0;
if (work_pending(work))
ret |= WORK_BUSY_PENDING;
return ret;
}
EXPORT_SYMBOL_GPL(work_busy);
void compat_system_workqueue_create()
{
system_wq = alloc_workqueue("events", 0, 0);
system_long_wq = alloc_workqueue("events_long", 0, 0);
system_nrt_wq = create_singlethread_workqueue("events_nrt");
BUG_ON(!system_wq || !system_long_wq || !system_nrt_wq);
}
void compat_system_workqueue_destroy()
{
destroy_workqueue(system_wq);
destroy_workqueue(system_long_wq);
destroy_workqueue(system_nrt_wq);
}
/*
* Copyright 2010 Hauke Mehrtens <hauke@hauke-m.de>
*
* 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.
*
* Compatibility file for Linux wireless for kernels 2.6.37.
*/
#include <linux/compat.h>
#include <linux/netdevice.h>
#include <net/sock.h>
#include <linux/nsproxy.h>
#include <linux/vmalloc.h>
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35)
static const void *net_current_ns(void)
{
return current->nsproxy->net_ns;
}
static const void *net_initial_ns(void)
{
return &init_net;
}
static const void *net_netlink_ns(struct sock *sk)
{
return sock_net(sk);
}
struct kobj_ns_type_operations net_ns_type_operations = {
.type = KOBJ_NS_TYPE_NET,
.current_ns = net_current_ns,
.netlink_ns = net_netlink_ns,
.initial_ns = net_initial_ns,
};
EXPORT_SYMBOL_GPL(net_ns_type_operations);
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35)*/
#undef genl_info
#undef genl_unregister_family
static LIST_HEAD(compat_nl_fam);
static struct genl_ops *genl_get_cmd(u8 cmd, struct genl_family *family)
{
struct genl_ops *ops;
list_for_each_entry(ops, &family->family.ops_list, ops.ops_list)
if (ops->cmd == cmd)
return ops;
return NULL;
}
static int nl_doit_wrapper(struct sk_buff *skb, struct genl_info *info)
{
struct compat_genl_info compat_info;
struct genl_family *family;
struct genl_ops *ops;
int err;
list_for_each_entry(family, &compat_nl_fam, list) {
if (family->id == info->nlhdr->nlmsg_type)
goto found;
}
return -ENOENT;
found:
ops = genl_get_cmd(info->genlhdr->cmd, family);
if (!ops)
return -ENOENT;
memset(&compat_info.user_ptr, 0, sizeof(compat_info.user_ptr));
compat_info.info = info;
#define __copy(_field) compat_info._field = info->_field
__copy(snd_seq);
__copy(snd_pid);
__copy(genlhdr);
__copy(attrs);
#undef __copy
if (family->pre_doit) {
err = family->pre_doit(ops, skb, &compat_info);
if (err)
return err;
}
err = ops->doit(skb, &compat_info);
if (family->post_doit)
family->post_doit(ops, skb, &compat_info);
return err;
}
int compat_genl_register_family_with_ops(struct genl_family *family,
struct genl_ops *ops, size_t n_ops)
{
int i, ret;
#define __copy(_field) family->family._field = family->_field
__copy(id);
__copy(hdrsize);
__copy(version);
__copy(maxattr);
strncpy(family->family.name, family->name, sizeof(family->family.name));
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32))
__copy(netnsok);
#endif
#undef __copy
ret = genl_register_family(&family->family);
if (ret < 0)
return ret;
family->attrbuf = family->family.attrbuf;
family->id = family->family.id;
for (i = 0; i < n_ops; i++) {
#define __copy(_field) ops[i].ops._field = ops[i]._field
__copy(cmd);
__copy(flags);
__copy(policy);
__copy(dumpit);
__copy(done);
#undef __copy
if (ops[i].doit)
ops[i].ops.doit = nl_doit_wrapper;
ret = genl_register_ops(&family->family, &ops[i].ops);
if (ret < 0)
goto error_ops;
}
list_add(&family->list, &compat_nl_fam);
return ret;
error_ops:
compat_genl_unregister_family(family);
return ret;
}
EXPORT_SYMBOL_GPL(compat_genl_register_family_with_ops);
int compat_genl_unregister_family(struct genl_family *family)
{
int err;
err = genl_unregister_family(&family->family);
list_del(&family->list);
return err;
}
EXPORT_SYMBOL_GPL(compat_genl_unregister_family);
#if defined(CONFIG_LEDS_CLASS) || defined(CONFIG_LEDS_CLASS_MODULE)
#undef led_brightness_set
#undef led_classdev_unregister
static DEFINE_SPINLOCK(led_lock);
static LIST_HEAD(led_timers);
struct led_timer {
struct list_head list;
struct led_classdev *cdev;
struct timer_list blink_timer;
unsigned long blink_delay_on;
unsigned long blink_delay_off;
int blink_brightness;
};
static void led_brightness_set(struct led_classdev *led_cdev,
enum led_brightness brightness)
{
led_cdev->brightness = brightness;
led_cdev->brightness_set(led_cdev, brightness);
}
static struct led_timer *led_get_timer(struct led_classdev *led_cdev)
{
struct led_timer *p;
unsigned long flags;
spin_lock_irqsave(&led_lock, flags);
list_for_each_entry(p, &led_timers, list) {
if (p->cdev == led_cdev)
goto found;
}
p = NULL;
found:
spin_unlock_irqrestore(&led_lock, flags);
return p;
}
static void led_stop_software_blink(struct led_timer *led)
{
del_timer_sync(&led->blink_timer);
led->blink_delay_on = 0;
led->blink_delay_off = 0;
}
static void led_timer_function(unsigned long data)
{
struct led_timer *led = (struct led_timer *)data;
unsigned long brightness;
unsigned long delay;
if (!led->blink_delay_on || !led->blink_delay_off) {
led->cdev->brightness_set(led->cdev, LED_OFF);
return;
}
brightness = led->cdev->brightness;
if (!brightness) {
/* Time to switch the LED on. */
brightness = led->blink_brightness;
delay = led->blink_delay_on;
} else {
/* Store the current brightness value to be able
* to restore it when the delay_off period is over.
*/
led->blink_brightness = brightness;
brightness = LED_OFF;
delay = led->blink_delay_off;
}
led_brightness_set(led->cdev, brightness);
mod_timer(&led->blink_timer, jiffies + msecs_to_jiffies(delay));
}
static struct led_timer *led_new_timer(struct led_classdev *led_cdev)
{
struct led_timer *led;
unsigned long flags;
led = kzalloc(sizeof(struct led_timer), GFP_ATOMIC);
if (!led)
return NULL;
led->cdev = led_cdev;
init_timer(&led->blink_timer);
led->blink_timer.function = led_timer_function;
led->blink_timer.data = (unsigned long) led;
spin_lock_irqsave(&led_lock, flags);
list_add(&led->list, &led_timers);
spin_unlock_irqrestore(&led_lock, flags);
return led;
}
void led_blink_set(struct led_classdev *led_cdev,
unsigned long *delay_on,
unsigned long *delay_off)
{
struct led_timer *led;
int current_brightness;
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,25))
if (led_cdev->blink_set &&
!led_cdev->blink_set(led_cdev, delay_on, delay_off))
return;
#endif
led = led_get_timer(led_cdev);
if (!led) {
led = led_new_timer(led_cdev);
if (!led)
return;
}
/* blink with 1 Hz as default if nothing specified */
if (!*delay_on && !*delay_off)
*delay_on = *delay_off = 500;
if (led->blink_delay_on == *delay_on &&
led->blink_delay_off == *delay_off)
return;
current_brightness = led_cdev->brightness;
if (current_brightness)
led->blink_brightness = current_brightness;
if (!led->blink_brightness)
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,30)
led->blink_brightness = led_cdev->max_brightness;
#else
led->blink_brightness = LED_FULL;
#endif
led_stop_software_blink(led);
led->blink_delay_on = *delay_on;
led->blink_delay_off = *delay_off;
/* never on - don't blink */
if (!*delay_on)
return;
/* never off - just set to brightness */
if (!*delay_off) {
led_brightness_set(led_cdev, led->blink_brightness);
return;
}
mod_timer(&led->blink_timer, jiffies + 1);
}
EXPORT_SYMBOL_GPL(led_blink_set);
void compat_led_brightness_set(struct led_classdev *led_cdev,
enum led_brightness brightness)
{
struct led_timer *led = led_get_timer(led_cdev);
if (led)
led_stop_software_blink(led);
return led_cdev->brightness_set(led_cdev, brightness);
}
EXPORT_SYMBOL_GPL(compat_led_brightness_set);
void compat_led_classdev_unregister(struct led_classdev *led_cdev)
{
struct led_timer *led = led_get_timer(led_cdev);
unsigned long flags;
if (led) {
del_timer_sync(&led->blink_timer);
spin_lock_irqsave(&led_lock, flags);
list_del(&led->list);
spin_unlock_irqrestore(&led_lock, flags);
kfree(led);
}
led_classdev_unregister(led_cdev);
}
EXPORT_SYMBOL_GPL(compat_led_classdev_unregister);
/**
* vzalloc - allocate virtually contiguous memory with zero fill
* @size: allocation size
* Allocate enough pages to cover @size from the page level
* allocator and map them into contiguous kernel virtual space.
* The memory allocated is set to zero.
*
* For tight control over page level allocator and protection flags
* use __vmalloc() instead.
*/
void *compat_vzalloc(unsigned long size)
{
void *buf;
buf = vmalloc(size);
if (buf)
memset(buf, 0, size);
return buf;
}
EXPORT_SYMBOL_GPL(compat_vzalloc);
#endif
/*
* Copyright 2010 Hauke Mehrtens <hauke@hauke-m.de>
*
* 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.
*
* Compatibility file for Linux wireless for kernels 2.6.38.
*/
#include <linux/compat.h>
#include <linux/module.h>
#include <linux/bug.h>
/**
* ewma_init() - Initialize EWMA parameters
* @avg: Average structure
* @factor: Factor to use for the scaled up internal value. The maximum value
* of averages can be ULONG_MAX/(factor*weight).
* @weight: Exponential weight, or decay rate. This defines how fast the
* influence of older values decreases. Has to be bigger than 1.
*
* Initialize the EWMA parameters for a given struct ewma @avg.
*/
void ewma_init(struct ewma *avg, unsigned long factor, unsigned long weight)
{
WARN_ON(weight <= 1 || factor == 0);
avg->internal = 0;
avg->weight = weight;
avg->factor = factor;
}
EXPORT_SYMBOL_GPL(ewma_init);
/**
* ewma_add() - Exponentially weighted moving average (EWMA)
* @avg: Average structure
* @val: Current value
*
* Add a sample to the average.
*/
struct ewma *ewma_add(struct ewma *avg, unsigned long val)
{
avg->internal = avg->internal ?
(((avg->internal * (avg->weight - 1)) +
(val * avg->factor)) / avg->weight) :
(val * avg->factor);
return avg;
}
EXPORT_SYMBOL_GPL(ewma_add);
/*
* Copyright 2011 Hauke Mehrtens <hauke@hauke-m.de>
*
* 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.
*
* Compatibility file for Linux wireless for kernels 2.6.39.
*/
#include <linux/compat.h>
#include <linux/tty.h>
#include <linux/sched.h>
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))
/*
* Termios Helper Methods
*/
static void unset_locked_termios(struct ktermios *termios,
struct ktermios *old,
struct ktermios *locked)
{
int i;
#define NOSET_MASK(x, y, z) (x = ((x) & ~(z)) | ((y) & (z)))
if (!locked) {
printk(KERN_WARNING "Warning?!? termios_locked is NULL.\n");
return;
}
NOSET_MASK(termios->c_iflag, old->c_iflag, locked->c_iflag);
NOSET_MASK(termios->c_oflag, old->c_oflag, locked->c_oflag);
NOSET_MASK(termios->c_cflag, old->c_cflag, locked->c_cflag);
NOSET_MASK(termios->c_lflag, old->c_lflag, locked->c_lflag);
termios->c_line = locked->c_line ? old->c_line : termios->c_line;
for (i = 0; i < NCCS; i++)
termios->c_cc[i] = locked->c_cc[i] ?
old->c_cc[i] : termios->c_cc[i];
/* FIXME: What should we do for i/ospeed */
}
/**
* tty_set_termios - update termios values
* @tty: tty to update
* @new_termios: desired new value
*
* Perform updates to the termios values set on this terminal. There
* is a bit of layering violation here with n_tty in terms of the
* internal knowledge of this function.
*
* Locking: termios_mutex
*/
int tty_set_termios(struct tty_struct *tty, struct ktermios *new_termios)
{
struct ktermios old_termios;
struct tty_ldisc *ld;
unsigned long flags;
/*
* Perform the actual termios internal changes under lock.
*/
/* FIXME: we need to decide on some locking/ordering semantics
for the set_termios notification eventually */
mutex_lock(&tty->termios_mutex);
old_termios = *tty->termios;
*tty->termios = *new_termios;
unset_locked_termios(tty->termios, &old_termios, tty->termios_locked);
/* See if packet mode change of state. */
if (tty->link && tty->link->packet) {
int extproc = (old_termios.c_lflag & EXTPROC) |
(tty->termios->c_lflag & EXTPROC);
int old_flow = ((old_termios.c_iflag & IXON) &&
(old_termios.c_cc[VSTOP] == '\023') &&
(old_termios.c_cc[VSTART] == '\021'));
int new_flow = (I_IXON(tty) &&
STOP_CHAR(tty) == '\023' &&
START_CHAR(tty) == '\021');
if ((old_flow != new_flow) || extproc) {
spin_lock_irqsave(&tty->ctrl_lock, flags);
if (old_flow != new_flow) {
tty->ctrl_status &= ~(TIOCPKT_DOSTOP | TIOCPKT_NOSTOP);
if (new_flow)
tty->ctrl_status |= TIOCPKT_DOSTOP;
else
tty->ctrl_status |= TIOCPKT_NOSTOP;
}
if (extproc)
tty->ctrl_status |= TIOCPKT_IOCTL;
spin_unlock_irqrestore(&tty->ctrl_lock, flags);
wake_up_interruptible(&tty->link->read_wait);
}
}
if (tty->ops->set_termios)
(*tty->ops->set_termios)(tty, &old_termios);
else
tty_termios_copy_hw(tty->termios, &old_termios);
ld = tty_ldisc_ref(tty);
if (ld != NULL) {
if (ld->ops->set_termios)
(ld->ops->set_termios)(tty, &old_termios);
tty_ldisc_deref(ld);
}
mutex_unlock(&tty->termios_mutex);
return 0;
}
EXPORT_SYMBOL_GPL(tty_set_termios);
#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)) */
/*
* Copyright 2011 Hauke Mehrtens <hauke@hauke-m.de>
* Copyright 2011 Alexey Dobriyan <adobriyan@gmail.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.
*
* Compatibility file for Linux wireless for kernels 3.0.
*/
#include <linux/compat.h>
#include <linux/if_ether.h>
int mac_pton(const char *s, u8 *mac)
{
int i;
/* XX:XX:XX:XX:XX:XX */
if (strlen(s) < 3 * ETH_ALEN - 1)
return 0;
/* Don't dirty result unless string is valid MAC. */
for (i = 0; i < ETH_ALEN; i++) {
if (!strchr("0123456789abcdefABCDEF", s[i * 3]))
return 0;
if (!strchr("0123456789abcdefABCDEF", s[i * 3 + 1]))
return 0;
if (i != ETH_ALEN - 1 && s[i * 3 + 2] != ':')
return 0;
}
for (i = 0; i < ETH_ALEN; i++) {
mac[i] = (hex_to_bin(s[i * 3]) << 4) | hex_to_bin(s[i * 3 + 1]);
}
return 1;
}
EXPORT_SYMBOL_GPL(mac_pton);
#define kstrto_from_user(f, g, type) \
int f(const char __user *s, size_t count, unsigned int base, type *res) \
{ \
/* sign, base 2 representation, newline, terminator */ \
char buf[1 + sizeof(type) * 8 + 1 + 1]; \
\
count = min(count, sizeof(buf) - 1); \
if (copy_from_user(buf, s, count)) \
return -EFAULT; \
buf[count] = '\0'; \
return g(buf, base, res); \
} \
EXPORT_SYMBOL_GPL(f)
kstrto_from_user(kstrtoull_from_user, kstrtoull, unsigned long long);
kstrto_from_user(kstrtoll_from_user, kstrtoll, long long);
kstrto_from_user(kstrtoul_from_user, kstrtoul, unsigned long);
kstrto_from_user(kstrtol_from_user, kstrtol, long);
kstrto_from_user(kstrtouint_from_user, kstrtouint, unsigned int);
kstrto_from_user(kstrtoint_from_user, kstrtoint, int);
kstrto_from_user(kstrtou16_from_user, kstrtou16, u16);
kstrto_from_user(kstrtos16_from_user, kstrtos16, s16);
kstrto_from_user(kstrtou8_from_user, kstrtou8, u8);
kstrto_from_user(kstrtos8_from_user, kstrtos8, s8);
/*
* Copyright 2012 Luis R. Rodriguez <mcgrof@frijolero.org>
*
* 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.
*
* Compatibility file for Linux wireless for kernels 3.2.
*/
#include <linux/kernel.h>
#include <linux/device.h>
int __netdev_printk(const char *level, const struct net_device *dev,
struct va_format *vaf)
{
int r;
if (dev && dev->dev.parent)
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35))
r = dev_printk(level, dev->dev.parent, "%s: %pV",
netdev_name(dev), vaf);
#else
/* XXX: this could likely be done better but I'm lazy */
r = printk("%s%s: %pV", level, netdev_name(dev), vaf);
#endif
else if (dev)
r = printk("%s%s: %pV", level, netdev_name(dev), vaf);
else
r = printk("%s(NULL net_device): %pV", level, vaf);
return r;
}
EXPORT_SYMBOL_GPL(__netdev_printk);
/*
* Copyright 2012 Luis R. Rodriguez <mcgrof@frijolero.org>
*
* 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.
*
* Compatibility file for Linux wireless for kernels 3.3.
*/
#include <linux/kernel.h>
#include <linux/version.h>
#include <linux/skbuff.h>
#include <linux/module.h>
#include <net/dst.h>
#include <net/xfrm.h>
static void __copy_skb_header(struct sk_buff *new, const struct sk_buff *old)
{
new->tstamp = old->tstamp;
new->dev = old->dev;
new->transport_header = old->transport_header;
new->network_header = old->network_header;
new->mac_header = old->mac_header;
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35))
skb_dst_copy(new, old);
new->rxhash = old->rxhash;
#else
skb_dst_set(new, dst_clone(skb_dst(old)));
#endif
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,1,0))
new->ooo_okay = old->ooo_okay;
#endif
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0))
new->l4_rxhash = old->l4_rxhash;
#endif
#ifdef CONFIG_XFRM
new->sp = secpath_get(old->sp);
#endif
memcpy(new->cb, old->cb, sizeof(old->cb));
new->csum = old->csum;
new->local_df = old->local_df;
new->pkt_type = old->pkt_type;
new->ip_summed = old->ip_summed;
skb_copy_queue_mapping(new, old);
new->priority = old->priority;
#if IS_ENABLED(CONFIG_IP_VS)
new->ipvs_property = old->ipvs_property;
#endif
new->protocol = old->protocol;
new->mark = old->mark;
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,33))
new->skb_iif = old->skb_iif;
#endif
__nf_copy(new, old);
#if IS_ENABLED(CONFIG_NETFILTER_XT_TARGET_TRACE)
new->nf_trace = old->nf_trace;
#endif
#ifdef CONFIG_NET_SCHED
new->tc_index = old->tc_index;
#ifdef CONFIG_NET_CLS_ACT
new->tc_verd = old->tc_verd;
#endif
#endif
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))
new->vlan_tci = old->vlan_tci;
#endif
skb_copy_secmark(new, old);
}
static void copy_skb_header(struct sk_buff *new, const struct sk_buff *old)
{
#ifndef NET_SKBUFF_DATA_USES_OFFSET
/*
* Shift between the two data areas in bytes
*/
unsigned long offset = new->data - old->data;
#endif
__copy_skb_header(new, old);
#ifndef NET_SKBUFF_DATA_USES_OFFSET
/* {transport,network,mac}_header are relative to skb->head */
new->transport_header += offset;
new->network_header += offset;
if (skb_mac_header_was_set(new))
new->mac_header += offset;
#endif
skb_shinfo(new)->gso_size = skb_shinfo(old)->gso_size;
skb_shinfo(new)->gso_segs = skb_shinfo(old)->gso_segs;
skb_shinfo(new)->gso_type = skb_shinfo(old)->gso_type;
}
static void skb_clone_fraglist(struct sk_buff *skb)
{
struct sk_buff *list;
skb_walk_frags(skb, list)
skb_get(list);
}
/**
* __pskb_copy - create copy of an sk_buff with private head.
* @skb: buffer to copy
* @headroom: headroom of new skb
* @gfp_mask: allocation priority
*
* Make a copy of both an &sk_buff and part of its data, located
* in header. Fragmented data remain shared. This is used when
* the caller wishes to modify only header of &sk_buff and needs
* private copy of the header to alter. Returns %NULL on failure
* or the pointer to the buffer on success.
* The returned buffer has a reference count of 1.
*/
struct sk_buff *__pskb_copy(struct sk_buff *skb, int headroom, gfp_t gfp_mask)
{
unsigned int size = skb_headlen(skb) + headroom;
struct sk_buff *n = alloc_skb(size, gfp_mask);
if (!n)
goto out;
/* Set the data pointer */
skb_reserve(n, headroom);
/* Set the tail pointer and length */
skb_put(n, skb_headlen(skb));
/* Copy the bytes */
skb_copy_from_linear_data(skb, n->data, n->len);
n->truesize += skb->data_len;
n->data_len = skb->data_len;
n->len = skb->len;
if (skb_shinfo(skb)->nr_frags) {
int i;
/*
* SKBTX_DEV_ZEROCOPY was added on 3.1 as well but requires ubuf
* stuff added to the skb which we do not have
*/
#if 0
if (skb_shinfo(skb)->tx_flags & SKBTX_DEV_ZEROCOPY) {
if (skb_copy_ubufs(skb, gfp_mask)) {
kfree_skb(n);
n = NULL;
goto out;
}
}
#endif
for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
skb_shinfo(n)->frags[i] = skb_shinfo(skb)->frags[i];
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0))
skb_frag_ref(skb, i);
#else
get_page(skb_shinfo(skb)->frags[i].page);
#endif
}
skb_shinfo(n)->nr_frags = i;
}
if (skb_has_frag_list(skb)) {
skb_shinfo(n)->frag_list = skb_shinfo(skb)->frag_list;
skb_clone_fraglist(n);
}
copy_skb_header(n, skb);
out:
return n;
}
EXPORT_SYMBOL_GPL(__pskb_copy);
/*
* Copyright 2012 Luis R. Rodriguez <mcgrof@frijolero.org>
*
* 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.
*
* Compatibility file for Linux wireless for kernels 3.5.
*/
#include <linux/fs.h>
#include <linux/module.h>
int simple_open(struct inode *inode, struct file *file)
{
if (inode->i_private)
file->private_data = inode->i_private;
return 0;
}
EXPORT_SYMBOL_GPL(simple_open);
#include <linux/spinlock.h>
#include <linux/module.h>
#if !((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,31)) && (defined(CONFIG_UML) || defined(CONFIG_X86))) && !((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,33)) && defined(CONFIG_ARM) && !defined(CONFIG_GENERIC_ATOMIC64))
static DEFINE_SPINLOCK(lock);
long long atomic64_read(const atomic64_t *v)
{
unsigned long flags;
long long val;
spin_lock_irqsave(&lock, flags);
val = v->counter;
spin_unlock_irqrestore(&lock, flags);
return val;
}
EXPORT_SYMBOL_GPL(atomic64_read);
long long atomic64_add_return(long long a, atomic64_t *v)
{
unsigned long flags;
long long val;
spin_lock_irqsave(&lock, flags);
val = v->counter += a;
spin_unlock_irqrestore(&lock, flags);
return val;
}
EXPORT_SYMBOL_GPL(atomic64_add_return);
#endif
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
kernel//home/thales/openair4G/openairITS/mac/DOT11/compat/compat.ko
This diff is collapsed.
#!/bin/sh
if [ -f /usr/bin/lsb_release ]; then
LSB_RED_ID=$(/usr/bin/lsb_release -i -s)
else
LSB_RED_ID="Unknown"
fi
case $LSB_RED_ID in
"Ubuntu")
mkdir -p /lib/udev/ /lib/udev/rules.d/
cp udev/ubuntu/compat_firmware.sh /lib/udev/
cp udev/ubuntu/50-compat_firmware.rules /lib/udev/rules.d/
;;
*)
mkdir -p /lib/udev/ /lib/udev/rules.d/
cp udev/compat_firmware.sh /lib/udev/
cp udev/50-compat_firmware.rules /lib/udev/rules.d/
;;
esac
#!/bin/bash
perl -pe 's|(\e)\[(\d+)(;*)(\d*)(\w)||g'
This diff is collapsed.
#include <linux/version.h>
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36)
#include <pcmcia/cs_types.h>
#endif
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,37)
#include <pcmcia/cs.h>
#endif
#include_next <pcmcia/cistpl.h>
#include <linux/version.h>
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,30))
#include_next <trace/define_trace.h>
#endif /* (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,30)) */
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
#include <linux/version.h>
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,37))
#include_next <linux/average.h>
#endif /* (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,37)) */
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment