From: Johannes Berg Date: Fri, 29 Mar 2013 18:57:47 +0000 (+0100) Subject: Merge compat code X-Git-Url: http://git.lede-project.org./?a=commitdiff_plain;h=0da76ef8674d0b04cf23dae2c98ed1625f7f64ac;p=openwrt%2Fstaging%2Fblogic.git Merge compat code --- 0da76ef8674d0b04cf23dae2c98ed1625f7f64ac diff --cc compat/.gitignore index 000000000000,000000000000..1331796276f7 new file mode 100644 --- /dev/null +++ b/compat/.gitignore @@@ -1,0 -1,0 +1,16 @@@ ++*~ ++Module.symvers ++module.order ++.pc ++ckmake.log ++.config ++include/linux/compat_autoconf.h ++.tmp_versions/ ++compat/*.cmd ++compat/*.o ++compat/*.mod.c ++compat/*.ko ++modules.order ++modules ++*.patch ++debs/ diff --cc compat/COPYRIGHT index 000000000000,000000000000..ca442d313d86 new file mode 100644 --- /dev/null +++ b/compat/COPYRIGHT @@@ -1,0 -1,0 +1,356 @@@ ++ ++ NOTE! This copyright does *not* cover user programs that use kernel ++ services by normal system calls - this is merely considered normal use ++ of the kernel, and does *not* fall under the heading of "derived work". ++ Also note that the GPL below is copyrighted by the Free Software ++ Foundation, but the instance of code that it refers to (the Linux ++ kernel) is copyrighted by me and others who actually wrote it. ++ ++ Also note that the only valid version of the GPL as far as the kernel ++ is concerned is _this_ particular version of the license (ie v2, not ++ v2.2 or v3.x or whatever), unless explicitly otherwise stated. ++ ++ Linus Torvalds ++ ++---------------------------------------- ++ ++ GNU GENERAL PUBLIC LICENSE ++ Version 2, June 1991 ++ ++ Copyright (C) 1989, 1991 Free Software Foundation, Inc. ++ 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ++ Everyone is permitted to copy and distribute verbatim copies ++ of this license document, but changing it is not allowed. ++ ++ Preamble ++ ++ The licenses for most software are designed to take away your ++freedom to share and change it. By contrast, the GNU General Public ++License is intended to guarantee your freedom to share and change free ++software--to make sure the software is free for all its users. This ++General Public License applies to most of the Free Software ++Foundation's software and to any other program whose authors commit to ++using it. (Some other Free Software Foundation software is covered by ++the GNU Library General Public License instead.) You can apply it to ++your programs, too. ++ ++ When we speak of free software, we are referring to freedom, not ++price. Our General Public Licenses are designed to make sure that you ++have the freedom to distribute copies of free software (and charge for ++this service if you wish), that you receive source code or can get it ++if you want it, that you can change the software or use pieces of it ++in new free programs; and that you know you can do these things. ++ ++ To protect your rights, we need to make restrictions that forbid ++anyone to deny you these rights or to ask you to surrender the rights. ++These restrictions translate to certain responsibilities for you if you ++distribute copies of the software, or if you modify it. ++ ++ For example, if you distribute copies of such a program, whether ++gratis or for a fee, you must give the recipients all the rights that ++you have. You must make sure that they, too, receive or can get the ++source code. And you must show them these terms so they know their ++rights. ++ ++ We protect your rights with two steps: (1) copyright the software, and ++(2) offer you this license which gives you legal permission to copy, ++distribute and/or modify the software. ++ ++ Also, for each author's protection and ours, we want to make certain ++that everyone understands that there is no warranty for this free ++software. If the software is modified by someone else and passed on, we ++want its recipients to know that what they have is not the original, so ++that any problems introduced by others will not reflect on the original ++authors' reputations. ++ ++ Finally, any free program is threatened constantly by software ++patents. We wish to avoid the danger that redistributors of a free ++program will individually obtain patent licenses, in effect making the ++program proprietary. To prevent this, we have made it clear that any ++patent must be licensed for everyone's free use or not licensed at all. ++ ++ The precise terms and conditions for copying, distribution and ++modification follow. ++ ++ GNU GENERAL PUBLIC LICENSE ++ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION ++ ++ 0. This License applies to any program or other work which contains ++a notice placed by the copyright holder saying it may be distributed ++under the terms of this General Public License. The "Program", below, ++refers to any such program or work, and a "work based on the Program" ++means either the Program or any derivative work under copyright law: ++that is to say, a work containing the Program or a portion of it, ++either verbatim or with modifications and/or translated into another ++language. (Hereinafter, translation is included without limitation in ++the term "modification".) Each licensee is addressed as "you". ++ ++Activities other than copying, distribution and modification are not ++covered by this License; they are outside its scope. The act of ++running the Program is not restricted, and the output from the Program ++is covered only if its contents constitute a work based on the ++Program (independent of having been made by running the Program). ++Whether that is true depends on what the Program does. ++ ++ 1. You may copy and distribute verbatim copies of the Program's ++source code as you receive it, in any medium, provided that you ++conspicuously and appropriately publish on each copy an appropriate ++copyright notice and disclaimer of warranty; keep intact all the ++notices that refer to this License and to the absence of any warranty; ++and give any other recipients of the Program a copy of this License ++along with the Program. ++ ++You may charge a fee for the physical act of transferring a copy, and ++you may at your option offer warranty protection in exchange for a fee. ++ ++ 2. You may modify your copy or copies of the Program or any portion ++of it, thus forming a work based on the Program, and copy and ++distribute such modifications or work under the terms of Section 1 ++above, provided that you also meet all of these conditions: ++ ++ a) You must cause the modified files to carry prominent notices ++ stating that you changed the files and the date of any change. ++ ++ b) You must cause any work that you distribute or publish, that in ++ whole or in part contains or is derived from the Program or any ++ part thereof, to be licensed as a whole at no charge to all third ++ parties under the terms of this License. ++ ++ c) If the modified program normally reads commands interactively ++ when run, you must cause it, when started running for such ++ interactive use in the most ordinary way, to print or display an ++ announcement including an appropriate copyright notice and a ++ notice that there is no warranty (or else, saying that you provide ++ a warranty) and that users may redistribute the program under ++ these conditions, and telling the user how to view a copy of this ++ License. (Exception: if the Program itself is interactive but ++ does not normally print such an announcement, your work based on ++ the Program is not required to print an announcement.) ++ ++These requirements apply to the modified work as a whole. If ++identifiable sections of that work are not derived from the Program, ++and can be reasonably considered independent and separate works in ++themselves, then this License, and its terms, do not apply to those ++sections when you distribute them as separate works. But when you ++distribute the same sections as part of a whole which is a work based ++on the Program, the distribution of the whole must be on the terms of ++this License, whose permissions for other licensees extend to the ++entire whole, and thus to each and every part regardless of who wrote it. ++ ++Thus, it is not the intent of this section to claim rights or contest ++your rights to work written entirely by you; rather, the intent is to ++exercise the right to control the distribution of derivative or ++collective works based on the Program. ++ ++In addition, mere aggregation of another work not based on the Program ++with the Program (or with a work based on the Program) on a volume of ++a storage or distribution medium does not bring the other work under ++the scope of this License. ++ ++ 3. You may copy and distribute the Program (or a work based on it, ++under Section 2) in object code or executable form under the terms of ++Sections 1 and 2 above provided that you also do one of the following: ++ ++ a) Accompany it with the complete corresponding machine-readable ++ source code, which must be distributed under the terms of Sections ++ 1 and 2 above on a medium customarily used for software interchange; or, ++ ++ b) Accompany it with a written offer, valid for at least three ++ years, to give any third party, for a charge no more than your ++ cost of physically performing source distribution, a complete ++ machine-readable copy of the corresponding source code, to be ++ distributed under the terms of Sections 1 and 2 above on a medium ++ customarily used for software interchange; or, ++ ++ c) Accompany it with the information you received as to the offer ++ to distribute corresponding source code. (This alternative is ++ allowed only for noncommercial distribution and only if you ++ received the program in object code or executable form with such ++ an offer, in accord with Subsection b above.) ++ ++The source code for a work means the preferred form of the work for ++making modifications to it. For an executable work, complete source ++code means all the source code for all modules it contains, plus any ++associated interface definition files, plus the scripts used to ++control compilation and installation of the executable. However, as a ++special exception, the source code distributed need not include ++anything that is normally distributed (in either source or binary ++form) with the major components (compiler, kernel, and so on) of the ++operating system on which the executable runs, unless that component ++itself accompanies the executable. ++ ++If distribution of executable or object code is made by offering ++access to copy from a designated place, then offering equivalent ++access to copy the source code from the same place counts as ++distribution of the source code, even though third parties are not ++compelled to copy the source along with the object code. ++ ++ 4. You may not copy, modify, sublicense, or distribute the Program ++except as expressly provided under this License. Any attempt ++otherwise to copy, modify, sublicense or distribute the Program is ++void, and will automatically terminate your rights under this License. ++However, parties who have received copies, or rights, from you under ++this License will not have their licenses terminated so long as such ++parties remain in full compliance. ++ ++ 5. You are not required to accept this License, since you have not ++signed it. However, nothing else grants you permission to modify or ++distribute the Program or its derivative works. These actions are ++prohibited by law if you do not accept this License. Therefore, by ++modifying or distributing the Program (or any work based on the ++Program), you indicate your acceptance of this License to do so, and ++all its terms and conditions for copying, distributing or modifying ++the Program or works based on it. ++ ++ 6. Each time you redistribute the Program (or any work based on the ++Program), the recipient automatically receives a license from the ++original licensor to copy, distribute or modify the Program subject to ++these terms and conditions. You may not impose any further ++restrictions on the recipients' exercise of the rights granted herein. ++You are not responsible for enforcing compliance by third parties to ++this License. ++ ++ 7. If, as a consequence of a court judgment or allegation of patent ++infringement or for any other reason (not limited to patent issues), ++conditions are imposed on you (whether by court order, agreement or ++otherwise) that contradict the conditions of this License, they do not ++excuse you from the conditions of this License. If you cannot ++distribute so as to satisfy simultaneously your obligations under this ++License and any other pertinent obligations, then as a consequence you ++may not distribute the Program at all. For example, if a patent ++license would not permit royalty-free redistribution of the Program by ++all those who receive copies directly or indirectly through you, then ++the only way you could satisfy both it and this License would be to ++refrain entirely from distribution of the Program. ++ ++If any portion of this section is held invalid or unenforceable under ++any particular circumstance, the balance of the section is intended to ++apply and the section as a whole is intended to apply in other ++circumstances. ++ ++It is not the purpose of this section to induce you to infringe any ++patents or other property right claims or to contest validity of any ++such claims; this section has the sole purpose of protecting the ++integrity of the free software distribution system, which is ++implemented by public license practices. Many people have made ++generous contributions to the wide range of software distributed ++through that system in reliance on consistent application of that ++system; it is up to the author/donor to decide if he or she is willing ++to distribute software through any other system and a licensee cannot ++impose that choice. ++ ++This section is intended to make thoroughly clear what is believed to ++be a consequence of the rest of this License. ++ ++ 8. If the distribution and/or use of the Program is restricted in ++certain countries either by patents or by copyrighted interfaces, the ++original copyright holder who places the Program under this License ++may add an explicit geographical distribution limitation excluding ++those countries, so that distribution is permitted only in or among ++countries not thus excluded. In such case, this License incorporates ++the limitation as if written in the body of this License. ++ ++ 9. The Free Software Foundation may publish revised and/or new versions ++of the General Public License from time to time. Such new versions will ++be similar in spirit to the present version, but may differ in detail to ++address new problems or concerns. ++ ++Each version is given a distinguishing version number. If the Program ++specifies a version number of this License which applies to it and "any ++later version", you have the option of following the terms and conditions ++either of that version or of any later version published by the Free ++Software Foundation. If the Program does not specify a version number of ++this License, you may choose any version ever published by the Free Software ++Foundation. ++ ++ 10. If you wish to incorporate parts of the Program into other free ++programs whose distribution conditions are different, write to the author ++to ask for permission. For software which is copyrighted by the Free ++Software Foundation, write to the Free Software Foundation; we sometimes ++make exceptions for this. Our decision will be guided by the two goals ++of preserving the free status of all derivatives of our free software and ++of promoting the sharing and reuse of software generally. ++ ++ NO WARRANTY ++ ++ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY ++FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN ++OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES ++PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED ++OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ++MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS ++TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE ++PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, ++REPAIR OR CORRECTION. ++ ++ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING ++WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR ++REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, ++INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING ++OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED ++TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY ++YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER ++PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE ++POSSIBILITY OF SUCH DAMAGES. ++ ++ END OF TERMS AND CONDITIONS ++ ++ How to Apply These Terms to Your New Programs ++ ++ If you develop a new program, and you want it to be of the greatest ++possible use to the public, the best way to achieve this is to make it ++free software which everyone can redistribute and change under these terms. ++ ++ To do so, attach the following notices to the program. It is safest ++to attach them to the start of each source file to most effectively ++convey the exclusion of warranty; and each file should have at least ++the "copyright" line and a pointer to where the full notice is found. ++ ++ ++ Copyright (C) ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ++ ++ ++Also add information on how to contact you by electronic and paper mail. ++ ++If the program is interactive, make it output a short notice like this ++when it starts in an interactive mode: ++ ++ Gnomovision version 69, Copyright (C) year name of author ++ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. ++ This is free software, and you are welcome to redistribute it ++ under certain conditions; type `show c' for details. ++ ++The hypothetical commands `show w' and `show c' should show the appropriate ++parts of the General Public License. Of course, the commands you use may ++be called something other than `show w' and `show c'; they could even be ++mouse-clicks or menu items--whatever suits your program. ++ ++You should also get your employer (if you work as a programmer) or your ++school, if any, to sign a "copyright disclaimer" for the program, if ++necessary. Here is a sample; alter the names: ++ ++ Yoyodyne, Inc., hereby disclaims all copyright interest in the program ++ `Gnomovision' (which makes passes at compilers) written by James Hacker. ++ ++ , 1 April 1989 ++ Ty Coon, President of Vice ++ ++This General Public License does not permit incorporating your program into ++proprietary programs. If your program is a subroutine library, you may ++consider it more useful to permit linking proprietary applications with the ++library. If this is what you want to do, use the GNU Library General ++Public License instead of this License. diff --cc compat/Makefile index 000000000000,469025e52992..cd4fc213a93e mode 000000,100644..100644 --- a/compat/Makefile +++ b/compat/Makefile @@@ -1,0 -1,64 +1,84 @@@ -ccflags-y += -I$(src) -obj-m += compat.o -#compat-objs := - -obj-$(CONFIG_COMPAT_FIRMWARE_CLASS) += compat_firmware_class.o -obj-$(CONFIG_COMPAT_NET_SCH_CODEL) += sch_codel.o - -sch_fq_codel-y = sch_fq_codel_core.o flow_dissector.o - -obj-$(CONFIG_COMPAT_NET_SCH_FQ_CODEL) += sch_fq_codel.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_34) += compat-2.6.34.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_1) += compat-3.1.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_4) += compat-3.4.o -compat-$(CONFIG_COMPAT_KERNEL_3_5) += \ - compat-3.5.o \ - user_namespace.o -compat-$(CONFIG_COMPAT_KERNEL_3_6) += compat-3.6.o -compat-$(CONFIG_COMPAT_KERNEL_3_7) += compat-3.7.o -compat-$(CONFIG_COMPAT_KERNEL_3_8) += compat-3.8.o -compat-$(CONFIG_COMPAT_KERNEL_3_9) += compat-3.9.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 ++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 ++ ++DESTDIR?= ++ ++ifeq ($(KERNELRELEASE),) ++export PWD := $(shell pwd) ++export COMPAT_BASE_TREE := "linux-next.git" ++# For this specific tree this is only relevant in ++# terms of the last time we synched code up with upstream ++# for internal stuff. For other compatability projects this ++# would be the git describe of the base tree you are ++# working with. ++export COMPAT_BASE_TREE_VERSION := "next-20100517" ++export COMPAT_VERSION := $(shell git describe) ++ ++# This is used to annotate what version of ++# compat.git was used. ++export COMPAT_BASE := $(shell git describe) ++ ++# to check config and compat autoconf ++export COMPAT_CONFIG=$(PWD)/.config ++export COMPAT_AUTOCONF=$(PWD)/include/linux/compat_autoconf.h ++export MAKE ++ ++else ++# By stuffing this hear we avoid using ++# this hackery on modpost, the 2nd section of module building. ++# ++# This hack lets us put our include path first than the kernel's ++# when building our compat modules. Your own makefile would look ++# the same. ++NOSTDINC_FLAGS := -I$(M)/include/ \ ++ -include $(M)/include/linux/compat-2.6.h \ ++ $(CFLAGS) \ ++ -DCOMPAT_BASE="\"$(COMPAT_BASE)\"" \ ++ -DCOMPAT_BASE_TREE="\"$(COMPAT_BASE_TREE)\"" \ ++ -DCOMPAT_BASE_TREE_VERSION="\"$(COMPAT_BASE_TREE_VERSION)\"" \ ++ -DCOMPAT_PROJECT="\"Generic kernel\"" \ ++ -DCOMPAT_VERSION="\"$(COMPAT_VERSION)\"" ++ ++# Technicallay we can require the inclusion of COMPAT_CONFIG for ++# all targets except clean, so avoid the warnings at clean time. ++-include $(COMPAT_CONFIG) + endif ++ ++obj-y += compat/ ++ ++all: modules ++ ++modules: $(COMPAT_CONFIG) $(COMPAT_AUTOCONF) ++ $(MAKE) -C $(KLIB_BUILD) M=$(PWD) modules ++ @touch modules ++ ++install: modules ++ $(MAKE) -C $(KLIB_BUILD) M=$(PWD) $(KMODDIR_ARG) $(KMODPATH_ARG) \ ++ modules_install ++ depmod -a ++ ++$(COMPAT_AUTOCONF): $(COMPAT_CONFIG) ++ +@$(PWD)/scripts/gen-compat-autoconf.sh $(COMPAT_CONFIG) > $(COMPAT_AUTOCONF) ++ ++$(COMPAT_CONFIG): ++ +@$(PWD)/scripts/gen-compat-config.sh > $(COMPAT_CONFIG) ++ ++install: modules ++ ++install-ckmake: ++ @mkdir -p $(DESTDIR)/usr/bin/ ++ @install bin/ckmake $(DESTDIR)/usr/bin/ ++ ++clean: ++ $(MAKE) -C $(KLIB_BUILD) M=$(PWD) clean ++ ++clean-files := Module.symvers modules.order Module.markers compat/modules.order ++clean-files += modules $(COMPAT_CONFIG) $(COMPAT_AUTOCONF) ++ ++.PHONY: all install clean modules Makefile diff --cc compat/README index 000000000000,000000000000..c9ff2c835e35 new file mode 100644 --- /dev/null +++ b/compat/README @@@ -1,0 -1,0 +1,8 @@@ ++compat ++======= ++ ++This is the Linux kernel backport compatibility module. ++ ++For more details please visit: ++ ++http://mcgrof.github.com/compat/ diff --cc compat/bin/ckmake index 000000000000,000000000000..cd9741aed9a3 new file mode 100755 --- /dev/null +++ b/compat/bin/ckmake @@@ -1,0 -1,0 +1,393 @@@ ++#!/usr/bin/env python ++ ++# ncurses Linux kernel cross kernel compilation utility ++ ++# Copyright (C) 2012 Luis R. Rodriguez ++# ++# 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. ++ ++import locale ++import curses ++import time ++import os ++import re ++import random ++import tempfile ++import subprocess ++import sys ++import signal ++ ++from Queue import * ++from threading import Thread, Lock ++from shutil import copytree, ignore_patterns, rmtree, copyfileobj ++from time import sleep ++ ++releases_processed = [] ++releases_baking = [] ++processed_lock = Lock() ++baking_lock = Lock() ++my_cwd = os.getcwd() ++ckmake_return = 0 ++ ++tmp_path = my_cwd + "/.tmp.ckmake" ++ckmake_log = my_cwd + "/ckmake.log" ++ckmake_report = my_cwd + "/ckmake-report.log" ++ ++home = os.getenv("HOME") ++ksrc = home + "/" + "compat-ksrc" ++modules = ksrc + "/lib/modules" ++ ++def clean(): ++ if os.path.exists(tmp_path): ++ rmtree(tmp_path) ++ ++def get_processed_rel(i): ++ "Because... list.pop(i) didn't work to keep order..." ++ processed_lock.acquire() ++ for rel in releases_processed: ++ if (rel['idx'] == i): ++ processed_lock.release() ++ return rel ++ processed_lock.release() ++ ++ baking_lock.acquire() ++ for rel in releases_baking: ++ if (rel['idx'] == i): ++ releases_baking.remove(rel) ++ baking_lock.release() ++ return rel ++ baking_lock.release() ++ ++def get_status_name(status): ++ if (status == 0): ++ return 'OK' ++ elif (status == 130): ++ return 'TERM' ++ elif (status == 1234): ++ return 'INIT' ++ elif (status == -2): ++ return 'TERM' ++ else: ++ return 'FAIL' ++ ++def get_stat_pos(status): ++ if (status == 0): ++ return 34 ++ elif (status == 130): ++ return 33 ++ elif (status == 1234): ++ return 33 ++ elif (status == -2): ++ return 33 ++ else: ++ return 33 ++ ++def get_status_color(status): ++ if (status == 0): ++ return curses.color_pair(1) ++ elif (status == 130): ++ return curses.color_pair(2) ++ elif (status == 1234): ++ return curses.color_pair(2) ++ elif (status == -2): ++ return curses.color_pair(2) ++ else: ++ return curses.color_pair(3) ++ ++def print_report(): ++ os.system("clear") ++ sys.stdout.write("\n\n\n") ++ sys.stdout.write("== ckmake-report.log ==\n\n") ++ report = open(ckmake_report, 'r+') ++ copyfileobj(report, sys.stdout) ++ report.close() ++ ++def process_logs(): ++ os.system('clear') ++ log = open(ckmake_log, 'w+') ++ report = open(ckmake_report, 'w+') ++ for i in range(0, len(releases_processed)): ++ rel = get_processed_rel(i) ++ rel_log = open(rel['log'], 'r+') ++ log.write(rel_log.read()) ++ status = get_status_name(rel['status']) ++ rel_report = "%-4s%-20s[ %s ]\n" % \ ++ ( rel['idx']+1, rel['version'], status) ++ report.write(rel_report) ++ if (rel['status'] != 0 and ++ rel['status'] != 2): ++ ckmake_return = -1 ++ report.close() ++ log.close() ++ print_report() ++ ++def process_kernel(num, kset): ++ while True: ++ rel = kset.queue.get() ++ work_dir = tmp_path + '/' + rel['version'] ++ copytree(my_cwd, \ ++ work_dir, \ ++ ignore=ignore_patterns('\.git*', '.tmp*', ".git")) ++ build = '%s/build/' % rel['full_path'] ++ jobs = ' -j%d ' % kset.build_jobs ++ make_args = 'KLIB=%(build)s KLIB_BUILD=%(build)s' % \ ++ { "build": build } ++ log_file = work_dir + '/' + 'ckmake.n.log' ++ rel['log'] = log_file ++ # XXX: figure out how to properly address logging ++ # without this nasty ass hack. ++ log = ' > %(log)s 2>&1' % { "log": log_file } ++ nice = 'ionice -c 3 nice -n 20 ' ++ cmd = nice + 'make ' + jobs + make_args + log ++ ++ my_env = os.environ.copy() ++ my_env["KCFLAGS"] = "-Wno-unused-but-set-variable" ++ ++ kset.baking(rel) ++ ++ p = subprocess.Popen([cmd], ++ env = my_env, ++ cwd = work_dir, ++ stdout=None, ++ stderr=None, ++ shell=True) ++ p.wait() ++ ++ kset.update_status(rel, p.returncode) ++ kset.queue.task_done() ++ kset.completed(rel) ++ ++def cpu_info_build_jobs(): ++ if not os.path.exists('/proc/cpuinfo'): ++ return 1 ++ f = open('/proc/cpuinfo', 'r') ++ max_cpus = 1 ++ for line in f: ++ m = re.match(r"(?Pprocessor\s*:)\s*" \ ++ "(?P\d+)", ++ line) ++ if not m: ++ continue ++ proc_specs = m.groupdict() ++ if (proc_specs['NUM'] > max_cpus): ++ max_cpus = proc_specs['NUM'] ++ return int(max_cpus) + 1 ++ ++def kill_curses(): ++ curses.endwin() ++ sys.stdout = os.fdopen(0, 'w', 0) ++ ++def sig_handler(signal, frame): ++ kill_curses() ++ process_logs() ++ clean() ++ sys.exit(-2) ++ ++def get_rel_spec(rel): ++ if ("rc" in rel): ++ m = re.match(r"v*(?P\d+)\.+" \ ++ "(?P\d+)[.]+" \ ++ "(?P\d+)[-]+" \ ++ "\d+rc(?P\d+)\-*", ++ rel) ++ else: ++ m = re.match(r"v*(?P\d+)\.+" \ ++ "(?P\d+)[.]+" \ ++ "(?P\d+)[-]+" \ ++ "(?P\d+)\-*", ++ rel) ++ if (not m): ++ return m ++ rel_specs = m.groupdict() ++ return rel_specs ++ ++def krel_same_base(new_rel, rel): ++ if (int(new_rel['ver']) != int(rel['ver'])): ++ return False ++ if (int(new_rel['pat']) != int(rel['pat'])): ++ return False ++ if (int(new_rel['ver']) == 3): ++ return True ++ if (int(new_rel['ver']) != 2): ++ return False ++ if (int(new_rel['sub']) == int(rel['sub'])): ++ return True ++ return False ++ ++def krel_base_update(new_rel, rel): ++ if (not krel_same_base(new_rel, rel)): ++ return False ++ if (int(new_rel['sub']) > int(rel['sub'])): ++ return True ++ if (int(new_rel['sub']) < int(rel['sub'])): ++ return False ++ ++ # Too lazy to deal with 2.x kernels, ++ if (not new_rel['is_rc']): ++ return False ++ ++ if (int(new_rel['ext']) <= int(rel['ext'])): ++ return False ++ return True ++ ++def krel_base_smaller(new_rel, rel): ++ if (not krel_same_base(new_rel, rel)): ++ return False ++ if (int(new_rel['sub']) > int(rel['sub'])): ++ return False ++ if (int(new_rel['sub']) < int(rel['sub'])): ++ return True ++ return False ++ ++class kernel_set(): ++ def __init__(self, stdscr): ++ self.queue = Queue() ++ self.releases = [] ++ self.stdscr = stdscr ++ self.lock = Lock() ++ signal.signal(signal.SIGINT, sig_handler) ++ self.build_jobs = cpu_info_build_jobs() ++ if (curses.has_colors()): ++ curses.init_pair(1, ++ curses.COLOR_GREEN, ++ curses.COLOR_BLACK) ++ curses.init_pair(2, ++ curses.COLOR_CYAN, ++ curses.COLOR_BLACK) ++ curses.init_pair(3, ++ curses.COLOR_RED, ++ curses.COLOR_BLACK) ++ curses.init_pair(4, ++ curses.COLOR_BLUE, ++ curses.COLOR_BLACK) ++ def baking(self, rel): ++ baking_lock.acquire() ++ releases_baking.append(rel) ++ baking_lock.release() ++ def completed(self, rel): ++ processed_lock.acquire() ++ releases_processed.insert(rel['idx'], rel) ++ processed_lock.release() ++ def set_locale(self): ++ locale.setlocale(locale.LC_ALL, '') ++ code = locale.getpreferredencoding() ++ def refresh(self): ++ self.lock.acquire() ++ self.stdscr.refresh() ++ self.lock.release() ++ def evaluate_new_rel(self, new_rel): ++ for rel in self.releases: ++ if (krel_base_update(new_rel, rel)): ++ new_rel['idx'] = rel['idx'] ++ self.releases.remove(rel) ++ break ++ if (krel_base_smaller(new_rel, rel)): ++ return ++ self.releases.insert(new_rel['idx'], new_rel) ++ def parse_releases(self): ++ for dirname, dirnames, filenames in os.walk(modules): ++ dirnames.sort() ++ for subdirname in dirnames: ++ specifics = get_rel_spec(subdirname) ++ if (not specifics): ++ continue ++ rc = False ++ ++ ver = specifics['VERSION'] + '.' + \ ++ specifics['PATCHLEVEL'] ++ ++ if ("rc" in subdirname): ++ rc = True ++ ver = ver + '-rc' + specifics['EXTRAVERSION'] ++ else: ++ ver = ver + '.' + specifics['SUBLEVEL'] ++ ++ rel = dict(idx=len(self.releases), ++ name=subdirname, ++ full_path=dirname + '/' + ++ subdirname, ++ version=ver, ++ is_rc = rc, ++ ver=specifics['VERSION'], ++ pat=specifics['PATCHLEVEL'], ++ sub=specifics['SUBLEVEL'], ++ ext=specifics['EXTRAVERSION'], ++ processed=False, ++ log='', ++ status=1234) ++ self.evaluate_new_rel(rel) ++ self.refresh() ++ def setup_screen(self): ++ for i in range(0, len(self.releases)): ++ rel = self.releases[i] ++ self.lock.acquire() ++ self.stdscr.addstr(rel['idx'], 0, ++ "%-4d" % (rel['idx']+1)) ++ if (curses.has_colors()): ++ self.stdscr.addstr(rel['idx'], 5, ++ "%-20s" % (rel['version']), ++ curses.color_pair(4)) ++ else: ++ self.stdscr.addstr(rel['idx'], 0, ++ "%-20s" % (rel['version'])) ++ self.stdscr.addstr(rel['idx'], 30, "[ ]") ++ self.stdscr.refresh() ++ self.lock.release() ++ def create_threads(self): ++ for rel in self.releases: ++ th = Thread(target=process_kernel, args=(0, self)) ++ th.setDaemon(True) ++ th.start() ++ def kick_threads(self): ++ for rel in self.releases: ++ self.queue.put(rel) ++ sleep(1) ++ def wait_threads(self): ++ self.queue.join() ++ def update_status(self, rel, status): ++ self.lock.acquire() ++ stat_name = get_status_name(status) ++ stat_pos = get_stat_pos(status) ++ if (curses.has_colors()): ++ stat_color = get_status_color(status) ++ self.stdscr.addstr(rel['idx'], stat_pos, stat_name, ++ get_status_color(status)) ++ else: ++ self.stdscr.addstr(rel['idx'], stat_pos, stat_name) ++ rel['processed'] = True ++ rel['status'] = status ++ self.stdscr.refresh() ++ self.lock.release() ++ ++def main(stdscr): ++ kset = kernel_set(stdscr) ++ ++ kset.set_locale() ++ kset.parse_releases() ++ kset.setup_screen() ++ kset.create_threads() ++ kset.kick_threads() ++ kset.wait_threads() ++ kset.refresh() ++ ++if __name__ == "__main__": ++ if not os.path.exists(modules): ++ print "%s does not exist" % (modules) ++ sys.exit(1) ++ if not os.path.exists(my_cwd + '/Makefile'): ++ print "%s does not exist" % (my_cwd + '/Makefile') ++ sys.exit(1) ++ if os.path.exists(ckmake_log): ++ os.remove(ckmake_log) ++ if os.path.exists(ckmake_report): ++ os.remove(ckmake_report) ++ if os.path.exists(tmp_path): ++ rmtree(tmp_path) ++ os.makedirs(tmp_path) ++ curses.wrapper(main) ++ kill_curses() ++ process_logs() ++ clean() ++ sys.exit(ckmake_return) diff --cc compat/bin/get-compat-kernels index 000000000000,000000000000..269dfd262d77 new file mode 100755 --- /dev/null +++ b/compat/bin/get-compat-kernels @@@ -1,0 -1,0 +1,265 @@@ ++#!/bin/bash ++# ++# Copyright (C) 2012, Luis R. Rodriguez ++# ++# 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. ++# ++# You can use this script to install all mainline kernels used ++# to test compile the Linux kernel compatibility module. You can ++# then use ckmake to cross compile against all supported kernels. ++ ++# Pretty colors ++GREEN="\033[01;32m" ++YELLOW="\033[01;33m" ++NORMAL="\033[00m" ++BLUE="\033[34m" ++RED="\033[31m" ++PURPLE="\033[35m" ++CYAN="\033[36m" ++UNDERLINE="\033[02m" ++ ++KERNELS="" ++KPATH="http://kernel.ubuntu.com/~kernel-ppa/mainline/" ++ ++FORCE="0" ++KSRC_PREFIX= ++# Check whether we're running as root or not ++# If we're root stuff things into /usr/src and /lib/modules ++# else, use $HOME/compat-ksrc for enabling user-mode builds. ++if [[ "$EUID" != "0" ]]; then ++ KSRC_PREFIX="$HOME/compat-ksrc" ++else ++ KSRC_PREFIX="${PWD}/compat-ksrc" ++fi ++ ++ ++# Create target directories if they doesn't exist ++mkdir -p $KSRC_PREFIX/{usr/src,lib/modules} ++ ++# List of currently supported kernels that will be downloaded ++KERNELS="$KERNELS ${KPATH}/v2.6.24/linux-headers-2.6.24-020624_2.6.24-020624_all.deb" ++KERNELS="$KERNELS ${KPATH}/v2.6.25/linux-headers-2.6.25-020625_2.6.25-020625_all.deb" ++KERNELS="$KERNELS ${KPATH}/v2.6.26/linux-headers-2.6.26-020626_2.6.26-020626_all.deb" ++KERNELS="$KERNELS ${KPATH}/v2.6.27/linux-headers-2.6.27-020627_2.6.27-020627_all.deb" ++KERNELS="$KERNELS ${KPATH}/v2.6.28.10/linux-headers-2.6.28-02062810_2.6.28-02062810_all.deb" ++KERNELS="$KERNELS ${KPATH}/v2.6.29.6/linux-headers-2.6.29-02062906_2.6.29-02062906_all.deb" ++KERNELS="$KERNELS ${KPATH}/v2.6.30.10/linux-headers-2.6.30-02063010_2.6.30-02063010_all.deb" ++KERNELS="$KERNELS ${KPATH}/v2.6.31.13-karmic/linux-headers-2.6.31-02063113_2.6.31-02063113_all.deb" ++KERNELS="$KERNELS ${KPATH}/v2.6.32.60-lucid/linux-headers-2.6.32-02063260_2.6.32-02063260.201210082135_all.deb" ++KERNELS="$KERNELS ${KPATH}/v2.6.33.20-maverick/linux-headers-2.6.33-02063320_2.6.33-02063320.201111071735_all.deb" ++KERNELS="$KERNELS ${KPATH}/v2.6.34.14-maverick/linux-headers-2.6.34-02063414_2.6.34-02063414.201301162135_all.deb" ++KERNELS="$KERNELS ${KPATH}/v2.6.35.13-original-maverick/linux-headers-2.6.35-02063513_2.6.35-02063513.201107261012_all.deb" ++KERNELS="$KERNELS ${KPATH}/v2.6.36.4-natty/linux-headers-2.6.36-02063604_2.6.36-02063604.201102180911_all.deb" ++KERNELS="$KERNELS ${KPATH}/v2.6.37.6-natty/linux-headers-2.6.37-02063706_2.6.37-02063706.201103281005_all.deb" ++KERNELS="$KERNELS ${KPATH}/v2.6.38.8-natty/linux-headers-2.6.38-02063808_2.6.38-02063808.201106040910_all.deb" ++KERNELS="$KERNELS ${KPATH}/v2.6.39.4-oneiric/linux-headers-2.6.39-02063904_2.6.39-02063904.201108040905_all.deb" ++KERNELS="$KERNELS ${KPATH}/v3.0.65-oneiric/linux-headers-3.0.65-030065_3.0.65-030065.201302171435_all.deb" ++KERNELS="$KERNELS ${KPATH}/v3.1.10-precise/linux-headers-3.1.10-030110_3.1.10-030110.201201181135_all.deb" ++KERNELS="$KERNELS ${KPATH}/v3.2.38-precise/linux-headers-3.2.38-030238_3.2.38-030238.201302060135_all.deb" ++KERNELS="$KERNELS ${KPATH}/v3.3.8-quantal/linux-headers-3.3.8-030308_3.3.8-030308.201206041356_all.deb" ++KERNELS="$KERNELS ${KPATH}/v3.4.32-quantal/linux-headers-3.4.32-030432_3.4.32-030432.201302171531_all.deb" ++KERNELS="$KERNELS ${KPATH}/v3.5.7-quantal/linux-headers-3.5.7-030507_3.5.7-030507.201210130556_all.deb" ++KERNELS="$KERNELS ${KPATH}/v3.6.11-raring/linux-headers-3.6.11-030611_3.6.11-030611.201212171335_all.deb" ++KERNELS="$KERNELS ${KPATH}/v3.7.9-raring/linux-headers-3.7.9-030709_3.7.9-030709.201302171607_all.deb" ++KERNELS="$KERNELS ${KPATH}/v3.8-raring/linux-headers-3.8.0-030800_3.8.0-030800.201302181935_all.deb" ++KERNELS="$KERNELS ${KPATH}/v3.9-rc1-raring/linux-headers-3.9.0-030900rc1_3.9.0-030900rc1.201303060659_all.deb" ++ ++# Number of kernels ++NUM_KERNELS=$(echo $KERNELS | wc -w) ++ ++# ~ 101 MiB for installed space on $KSRC_PREFIX/usr/src/ and $KSRC_PREFIX/lib/modules/ ++SPACE_PER_KERNEL="101" ++ ++# ~13 MiB of both deb files ++SPACE_PER_KERNEL_DEB="13" ++ ++function get_ubuntu_kernels() { ++ ++ ARCH=$(uname -m) ++ TARGET="" ++ ++ case $ARCH in ++ "x86_64") ++ TARGET="amd64" ++ ;; ++ "i686") ++ TARGET="i386" ++ ;; ++ *) ++ echo -e "Unsupported architecture" ++ exit ++ ;; ++ esac ++ ++ mkdir -p debs ++ cd debs ++ ++ for i in $KERNELS; do ++ FILE=$(basename $i) ++ PKG=$(echo $FILE | awk -F"_" '{print $1}') ++ ++ # Do not download if installed or deb exists ++ if [[ ! -d $KSRC_PREFIX/usr/src/$PKG && ! -f $FILE ]]; then ++ # Download the _all.deb ++ wget -c $i ++ ++ # Download the generic-ARCH headers ++ GENERIC_DEB=`echo $i | sed -e "s:\(.*\)_\(.*\)_all.deb:\1-generic_\2_$TARGET.deb:"` ++ wget -c $GENERIC_DEB ++ fi ++ done ++ ++ # List of downloaded debs ++ DEB_LIST=`ls linux-*.deb 2>/dev/null` ++ ++ if [[ -z $DEB_LIST ]]; then ++ echo "All kernel sources are found in $KSRC_PREFIX/usr/src." ++ exit ++ fi ++ ++ # Create a temporary directory first ++ TEMP_DIR=`mktemp -d` ++ ++ for deb in $DEB_LIST; do ++ DIR_NAME=$(echo $deb | awk -F"_" '{print $1}') ++ if [[ ! -d $KSRC_PREFIX/usr/src/$DIR_NAME ]]; then ++ echo "Extracting $deb..." ++ ar p $deb data.tar.gz | tar xz --exclude=usr/share -C $TEMP_DIR ++ fi ++ done ++ ++ # Move the extracted folders into the system ++ if [[ -d $TEMP_DIR/lib/modules ]]; then ++ ++ # Relink lib/modules/*/build/ directories relatively to make it work ++ # for regular user based workflows ++ if [[ -n $KSRC_PREFIX ]]; then ++ echo "Adjusting build/ symlinks for non-root installation..." ++ ++ for kernel in $(ls -d $TEMP_DIR/lib/modules/*generic); do ++ unlink $kernel/build ++ ln -s ../../../usr/src/linux-headers-`basename $kernel` $kernel/build ++ done ++ fi ++ ++ mv $TEMP_DIR/lib/modules/* $KSRC_PREFIX/lib/modules ++ fi ++ if [[ -d $TEMP_DIR/usr/src ]]; then ++ # Because of a bug in make < 3.82, mixed implicit and normal ++ # rules do not cause harm. Since the bug is fixed in the new make ++ # we have to adjust older kernel's Makefiles to fix the bug. ++ sed -i 's#^/ %/:#%/:#' $TEMP_DIR/usr/src/linux-headers-2.6.2[45678]-0*/Makefile &>/dev/null ++ ++ mv $TEMP_DIR/usr/src/* $KSRC_PREFIX/usr/src ++ fi ++ ++ # Remove the temporary directory ++ rm -rf $TEMP_DIR ++} ++ ++function rebuild_header_binary_deps() { ++ if [[ ! -d ${KSRC_PREFIX}/lib/modules/ ]]; then ++ echo "You do not seem to have any vanilla kernels available to fix" ++ exit 1 ++ fi ++ ++ COUNT=$(ls -d ${KSRC_PREFIX}/lib/modules/*generic | wc -l) ++ if [[ $COUNT -le 0 ]]; then ++ echo "You do not seem to have any vanilla kernels available to fix" ++ exit 1 ++ fi ++ ++ for kernel in $(ls -d ${KSRC_PREFIX}/lib/modules/*generic | grep -E "/3.[2-9]|/[4-9]"); do ++ echo $kernel ++ ++ count=0 ++ while [[ $count -ne 4 ]]; do ++ for i in basic mod genksyms; do ++ if [[ $count -eq 0 ]]; then ++ make -C ${kernel}/build/ M=scripts/${i}/ clean > /dev/null 2>&1 ++ fi ++ make -C ${kernel}/build/ M=scripts/${i}/ > /dev/null 2>&1 ++ done ++ let count=$count+1 ++ done ++ done ++} ++ ++function usage() { ++ echo -e "Usage: $0 [ -r ] [ -f ] " ++ echo -e "-r Rebuilds binaries required in kernel headers. Use" ++ echo -e " this option if you've already ran this script and" ++ echo -e " just need to fix the libc versions against which" ++ echo -e " the binaries in the headers files are linked against. " ++ echo -e " This was added since kernels >= 3.4 require" ++ echo -e " a glibc >= 2.14 for memcpy(), and not all Linux" ++ echo -e " distributions have such versions of glibc." ++ echo -e "" ++ echo -e "-f Force running, do not ask" ++} ++ ++if [[ $# -gt 3 ]]; then ++ usage ++ exit 1 ++fi ++ ++if [[ $1 == "-r" ]]; then ++ rebuild_header_binary_deps ++ exit ++fi ++ ++if [[ $1 == "-f" ]]; then ++ FORCE="1" ++ shift ++fi ++ ++# Check for the availability of 'ar' before continuing ++which ar 2>&1 > /dev/null ++if [[ $? -ne 0 ]]; then ++ echo -e "${GREEN}ar${NORMAL} is not avilable, typically this is available through a package called binutils" ++ echo -e "Install binutils and run this script again..." ++ exit 1 ++fi ++ ++echo -e "" ++ ++if [[ ! -n $KSRC_PREFIX ]]; then ++ echo -e "** Running as a privileged user!" ++ echo -e "** You are trying to force using ${BLUE}${KSRC_PREFIX}/lib/modules${NORMAL} and ${BLUE}${KSRC_PREFIX}/usr/src${NORMAL} ..." ++ echo -e "** This is a terrible idea. Consider running as a regular user." ++ echo -e "" ++ read -p "Do you still want to continue (y/N)? " ++ if [[ "${REPLY}" != "y" ]]; then ++ echo -e "Bailing out !" ++ exit 1 ++ fi ++fi ++ ++echo -e "This will download ${YELLOW}${NUM_KERNELS}${NORMAL} kernel headers to allow you to" ++echo -e "cross compile any module over these kernels with ${GREEN}ckmake${NORMAL}." ++echo -e "The download payload is about ${YELLOW}~ $((${SPACE_PER_KERNEL_DEB} * ${NUM_KERNELS})) ${CYAN}MiB${NORMAL}, once uncompressed" ++echo -e "it will stash kernel header files under ${BLUE}$KSRC_PREFIX/usr/src/${NORMAL}" ++echo -e "and ${BLUE}$KSRC_PREFIX/lib/modules/${NORMAL} and consume about ~ ${YELLOW}$((${NUM_KERNELS} * ${SPACE_PER_KERNEL})) ${RED}MiB${NORMAL} of space." ++echo -e "" ++echo -e "The kernel headers used are from ${PURPLE}${UNDERLINE}Vanilla${NORMAL} kernels" ++echo -e "from the Ubuntu mainline / vanilla kernel PPA and are extracted" ++echo -e "using ${GREEN}ar${NORMAL} and ${GREEN}tar${NORMAL}:" ++echo -e "" ++echo -e "${BLUE}http://kernel.ubuntu.com/~kernel-ppa/mainline/${NORMAL}" ++echo -e "" ++ ++if [[ "$FORCE" != "1" ]]; then ++ read -p "Do you still want to continue (y/N)? " ++ if [[ "${REPLY}" != "y" ]]; then ++ echo -e "Bailing out !" ++ exit 1 ++ fi ++fi ++ ++get_ubuntu_kernels ++echo -e "Vanilla kernels headers ${BLUE}installed${NORMAL}, " ++echo -e "now going to ${GREEN}rebuild${NORMAL} some binary dependencies..." ++sleep 1 ++rebuild_header_binary_deps diff --cc compat/bin/get-compat-trees index 000000000000,000000000000..d7812457f65f new file mode 100755 --- /dev/null +++ b/compat/bin/get-compat-trees @@@ -1,0 -1,0 +1,87 @@@ ++#!/bin/bash ++# ++# Copyright (C) 2012, Luis R. Rodriguez ++# ++# 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. ++# ++# You can use this script to install all mainline kernels used ++# to test compile the Linux kernel compatibility module. You can ++# then use ckmake to cross compile against all supported kernels. ++ ++# Pretty colors ++GREEN="\033[01;32m" ++YELLOW="\033[01;33m" ++NORMAL="\033[00m" ++BLUE="\033[34m" ++RED="\033[31m" ++PURPLE="\033[35m" ++CYAN="\033[36m" ++UNDERLINE="\033[02m" ++ ++PREFIX=$HOME/ ++ ++GIT_TREES="git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git" ++GIT_TREES="$GIT_TREES git://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git" ++GIT_TREES="$GIT_TREES git://github.com/mcgrof/compat.git" ++GIT_TREES="$GIT_TREES git://github.com/mcgrof/compat-drivers.git" ++ ++LINUX_GIT="git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git" ++ ++which git 2>&1 > /dev/null ++if [[ $? -ne 0 ]]; then ++ echo -e "You need to install ${PURPLE}git${NORMAL}" ++ exit 1 ++fi ++ ++echo -e "This will typically take ~ ${YELLOW}10 ${CYAN}minutes${NORMAL}, download about " ++echo -e "~ ${YELLOW}1 ${CYAN}GiB${NORMAL} of data over your network, and then consume about " ++echo -e "~ ${YELLOW}2 ${CYAN}GiB${NORMAL} of hard drive space." ++ ++read -p "Do you still want to continue (y/N)? " ++if [[ "${REPLY}" != "y" ]]; then ++ echo -e "Bailing out !" ++ exit 1 ++fi ++ ++mkdir -p $PREFIX ++cd $PREFIX ++ ++for i in $GIT_TREES; do ++ TREE=$(echo ${i} | awk -F"/" '{print $NF}') ++ ++ if [[ -d $PREFIX/$TREE ]]; then ++ echo "${GREEN}${TREE}${NORMAL} is already present, skipping..." ++ continue ++ fi ++ ++ echo -e "Cloning ${GREEN}${TREE}${NORMAL}..." ++ ++ case $TREE in ++ "linux-stable.git") ++ cd $PREFIX/ ++ git clone $i ++ ++ cd $PREFIX/linux-stable ++ # This lets us bake releases off of Linus' RC releases by ++ # simply git fetch'ing "linus" and reseting the tree afterwards. ++ git remote add linus $LINUX_GIT ++ ;; ++ "linux-next.git") ++ cd $PREFIX ++ git clone $i --reference $PREFIX/linux-stable/.git/ ++ ;; ++ "compat-drivers.git") ++ # This is just what scripts are tested for. Probably best to ++ # unify all into one place but this will do for now. ++ mkdir -p $PREFIX/devel/ ++ cd $PREFIX/devel/ ++ git clone $i ++ ;; ++ *) ++ cd $PREFIX ++ git clone $i ++ ;; ++ esac ++done diff --cc compat/compat/Makefile index 000000000000,000000000000..469025e52992 new file mode 100644 --- /dev/null +++ b/compat/compat/Makefile @@@ -1,0 -1,0 +1,64 @@@ ++ccflags-y += -I$(src) ++obj-m += compat.o ++#compat-objs := ++ ++obj-$(CONFIG_COMPAT_FIRMWARE_CLASS) += compat_firmware_class.o ++obj-$(CONFIG_COMPAT_NET_SCH_CODEL) += sch_codel.o ++ ++sch_fq_codel-y = sch_fq_codel_core.o flow_dissector.o ++ ++obj-$(CONFIG_COMPAT_NET_SCH_FQ_CODEL) += sch_fq_codel.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_34) += compat-2.6.34.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_1) += compat-3.1.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_4) += compat-3.4.o ++compat-$(CONFIG_COMPAT_KERNEL_3_5) += \ ++ compat-3.5.o \ ++ user_namespace.o ++compat-$(CONFIG_COMPAT_KERNEL_3_6) += compat-3.6.o ++compat-$(CONFIG_COMPAT_KERNEL_3_7) += compat-3.7.o ++compat-$(CONFIG_COMPAT_KERNEL_3_8) += compat-3.8.o ++compat-$(CONFIG_COMPAT_KERNEL_3_9) += compat-3.9.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 diff --cc compat/compat/compat-2.6.14.c index 000000000000,000000000000..3de847d9d057 new file mode 100644 --- /dev/null +++ b/compat/compat/compat-2.6.14.c @@@ -1,0 -1,0 +1,14 @@@ ++/* ++ * Copyright 2007 Luis R. Rodriguez ++ * ++ * 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 ++ ++/* 2.6.14 compat code goes here */ ++ diff --cc compat/compat/compat-2.6.18.c index 000000000000,000000000000..c7961eeba92b new file mode 100644 --- /dev/null +++ b/compat/compat/compat-2.6.18.c @@@ -1,0 -1,0 +1,14 @@@ ++/* ++ * Copyright 2007 Luis R. Rodriguez ++ * ++ * 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 ++ ++/* 2.6.18 compat code goes here */ ++ diff --cc compat/compat/compat-2.6.19.c index 000000000000,000000000000..60c340458098 new file mode 100644 --- /dev/null +++ b/compat/compat/compat-2.6.19.c @@@ -1,0 -1,0 +1,14 @@@ ++/* ++ * Copyright 2007 Luis R. Rodriguez ++ * ++ * 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 ++ ++/* 2.6.19 compat code goes here */ ++ diff --cc compat/compat/compat-2.6.21.c index 000000000000,000000000000..7cf886194bd3 new file mode 100644 --- /dev/null +++ b/compat/compat/compat-2.6.21.c @@@ -1,0 -1,0 +1,14 @@@ ++/* ++ * Copyright 2007 Luis R. Rodriguez ++ * ++ * 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 ++ ++/* 2.6.21 compat code goes here */ ++ diff --cc compat/compat/compat-2.6.22.c index 000000000000,000000000000..d4df7b7d8d51 new file mode 100644 --- /dev/null +++ b/compat/compat/compat-2.6.22.c @@@ -1,0 -1,0 +1,14 @@@ ++/* ++ * Copyright 2007 Luis R. Rodriguez ++ * ++ * 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 ++ ++/* 2.6.22 compat code goes here */ ++ diff --cc compat/compat/compat-2.6.23.c index 000000000000,000000000000..1a76957db0fd new file mode 100644 --- /dev/null +++ b/compat/compat/compat-2.6.23.c @@@ -1,0 -1,0 +1,241 @@@ ++/* ++ * Copyright 2007 Luis R. Rodriguez ++ * ++ * 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 ++ ++/* On net/core/dev.c as of 2.6.24 */ ++#define __dev_addr_delete LINUX_BACKPORT(__dev_addr_delete) ++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 */ ++#define __dev_addr_add LINUX_BACKPORT(__dev_addr_add) ++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 ++ diff --cc compat/compat/compat-2.6.24.c index 000000000000,000000000000..977db0ca170c new file mode 100644 --- /dev/null +++ b/compat/compat/compat-2.6.24.c @@@ -1,0 -1,0 +1,158 @@@ ++/* ++ * Copyright 2007 Luis R. Rodriguez ++ * ++ * 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 ++#include ++ ++/* ++ * 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); ++ diff --cc compat/compat/compat-2.6.25.c index 000000000000,000000000000..20cc3dbd5fe0 new file mode 100644 --- /dev/null +++ b/compat/compat/compat-2.6.25.c @@@ -1,0 -1,0 +1,305 @@@ ++/* ++ * Copyright 2007-2012 Luis R. Rodriguez ++ * ++ * 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 ++#include ++ ++/* ++ * The default behaviour of sg_alloc_table() is to use these kmalloc/kfree ++ * helpers. ++ */ ++static struct scatterlist *sg_kmalloc(unsigned int nents, gfp_t gfp_mask) ++{ ++ if (nents == SG_MAX_SINGLE_ALLOC) { ++ return (struct scatterlist *) __get_free_page(gfp_mask); ++ } else ++ return kmalloc(nents * sizeof(struct scatterlist), gfp_mask); ++} ++ ++static void sg_kfree(struct scatterlist *sg, unsigned int nents) ++{ ++ if (nents == SG_MAX_SINGLE_ALLOC) ++ free_page((unsigned long) sg); ++ else ++ kfree(sg); ++} ++ ++ ++/** ++ * __sg_free_table - Free a previously mapped sg table ++ * @table: The sg table header to use ++ * @max_ents: The maximum number of entries per single scatterlist ++ * @free_fn: Free function ++ * ++ * Description: ++ * Free an sg table previously allocated and setup with ++ * __sg_alloc_table(). The @max_ents value must be identical to ++ * that previously used with __sg_alloc_table(). ++ * ++ **/ ++void __sg_free_table(struct sg_table *table, unsigned int max_ents, ++ sg_free_fn *free_fn) ++{ ++ struct scatterlist *sgl, *next; ++ ++ if (unlikely(!table->sgl)) ++ return; ++ ++ sgl = table->sgl; ++ while (table->orig_nents) { ++ unsigned int alloc_size = table->orig_nents; ++ unsigned int sg_size; ++ ++ /* ++ * If we have more than max_ents segments left, ++ * then assign 'next' to the sg table after the current one. ++ * sg_size is then one less than alloc size, since the last ++ * element is the chain pointer. ++ */ ++ if (alloc_size > max_ents) { ++ next = sg_chain_ptr(&sgl[max_ents - 1]); ++ alloc_size = max_ents; ++ sg_size = alloc_size - 1; ++ } else { ++ sg_size = alloc_size; ++ next = NULL; ++ } ++ ++ table->orig_nents -= sg_size; ++ free_fn(sgl, alloc_size); ++ sgl = next; ++ } ++ ++ table->sgl = NULL; ++} ++EXPORT_SYMBOL(__sg_free_table); ++ ++/** ++ * sg_free_table - Free a previously allocated sg table ++ * @table: The mapped sg table header ++ * ++ **/ ++void sg_free_table(struct sg_table *table) ++{ ++ __sg_free_table(table, SG_MAX_SINGLE_ALLOC, sg_kfree); ++} ++EXPORT_SYMBOL(sg_free_table); ++ ++/** ++ * __sg_alloc_table - Allocate and initialize an sg table with given allocator ++ * @table: The sg table header to use ++ * @nents: Number of entries in sg list ++ * @max_ents: The maximum number of entries the allocator returns per call ++ * @gfp_mask: GFP allocation mask ++ * @alloc_fn: Allocator to use ++ * ++ * Description: ++ * This function returns a @table @nents long. The allocator is ++ * defined to return scatterlist chunks of maximum size @max_ents. ++ * Thus if @nents is bigger than @max_ents, the scatterlists will be ++ * chained in units of @max_ents. ++ * ++ * Notes: ++ * If this function returns non-0 (eg failure), the caller must call ++ * __sg_free_table() to cleanup any leftover allocations. ++ * ++ **/ ++int __sg_alloc_table(struct sg_table *table, unsigned int nents, ++ unsigned int max_ents, gfp_t gfp_mask, ++ sg_alloc_fn *alloc_fn) ++{ ++ struct scatterlist *sg, *prv; ++ unsigned int left; ++ ++#ifndef ARCH_HAS_SG_CHAIN ++ if (WARN_ON_ONCE(nents > max_ents)) ++ return -EINVAL; ++#endif ++ ++ memset(table, 0, sizeof(*table)); ++ ++ left = nents; ++ prv = NULL; ++ do { ++ unsigned int sg_size, alloc_size = left; ++ ++ if (alloc_size > max_ents) { ++ alloc_size = max_ents; ++ sg_size = alloc_size - 1; ++ } else ++ sg_size = alloc_size; ++ ++ left -= sg_size; ++ ++ sg = alloc_fn(alloc_size, gfp_mask); ++ if (unlikely(!sg)) { ++ /* ++ * Adjust entry count to reflect that the last ++ * entry of the previous table won't be used for ++ * linkage. Without this, sg_kfree() may get ++ * confused. ++ */ ++ if (prv) ++ table->nents = ++table->orig_nents; ++ ++ return -ENOMEM; ++ } ++ ++ sg_init_table(sg, alloc_size); ++ table->nents = table->orig_nents += sg_size; ++ ++ /* ++ * If this is the first mapping, assign the sg table header. ++ * If this is not the first mapping, chain previous part. ++ */ ++ if (prv) ++ sg_chain(prv, max_ents, sg); ++ else ++ table->sgl = sg; ++ ++ /* ++ * If no more entries after this one, mark the end ++ */ ++ if (!left) ++ sg_mark_end(&sg[sg_size - 1]); ++ ++ prv = sg; ++ } while (left); ++ ++ return 0; ++} ++EXPORT_SYMBOL(__sg_alloc_table); ++ ++/** ++ * sg_alloc_table - Allocate and initialize an sg table ++ * @table: The sg table header to use ++ * @nents: Number of entries in sg list ++ * @gfp_mask: GFP allocation mask ++ * ++ * Description: ++ * Allocate and initialize an sg table. If @nents@ is larger than ++ * SG_MAX_SINGLE_ALLOC a chained sg table will be setup. ++ * ++ **/ ++int sg_alloc_table(struct sg_table *table, unsigned int nents, gfp_t gfp_mask) ++{ ++ int ret; ++ ++ ret = __sg_alloc_table(table, nents, SG_MAX_SINGLE_ALLOC, ++ gfp_mask, sg_kmalloc); ++ if (unlikely(ret)) ++ __sg_free_table(table, SG_MAX_SINGLE_ALLOC, sg_kfree); ++ ++ return ret; ++} ++EXPORT_SYMBOL(sg_alloc_table); ++ ++ ++/* ++ * To backport b718989d correctly pcibios_enable_device() ++ * is required but we don't have access to it on modules ++ * as its an architecture specific routine that is not ++ * exported and as such only core kernel code has access ++ * to it. We implement a sloppy work around for backporting ++ * this. ++ */ ++int pci_enable_device_mem(struct pci_dev *dev) ++{ ++ int bars = pci_select_bars(dev, IORESOURCE_MEM); ++ ++ return pci_enable_device_bars(dev, bars); ++} ++EXPORT_SYMBOL_GPL(pci_enable_device_mem); ++ ++/** ++ * 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); ++ diff --cc compat/compat/compat-2.6.26.c index 000000000000,000000000000..f4715067511f new file mode 100644 --- /dev/null +++ b/compat/compat/compat-2.6.26.c @@@ -1,0 -1,0 +1,87 @@@ ++/* ++ * Copyright 2007-2010 Luis R. Rodriguez ++ * ++ * 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 ++ * Copyright (c) 2006-2007 Greg Kroah-Hartman ++ * Copyright (c) 2006-2007 Novell Inc. ++ */ ++ ++#include ++ ++/* 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); ++ diff --cc compat/compat/compat-2.6.27.c index 000000000000,000000000000..084bdf6dfc4a new file mode 100644 --- /dev/null +++ b/compat/compat/compat-2.6.27.c @@@ -1,0 -1,0 +1,239 @@@ ++/* ++ * Copyright 2007 Luis R. Rodriguez ++ * ++ * 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 ++#include ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)) ++#include ++#include ++#include ++#include ++#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-drivers, 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 */ ++ diff --cc compat/compat/compat-2.6.28.c index 000000000000,000000000000..0ae8f465dbb6 new file mode 100644 --- /dev/null +++ b/compat/compat/compat-2.6.28.c @@@ -1,0 -1,0 +1,463 @@@ ++/* ++ * Copyright 2007 Luis R. Rodriguez ++ * ++ * 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.28. ++ */ ++ ++#include ++#include ++#include ++#include ++ ++/* 2.6.28 compat code goes here */ ++ ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23)) ++#if defined(CONFIG_USB) || defined(CONFIG_USB_MODULE) ++/* ++ * Compat-wireless notes for USB backport stuff: ++ * ++ * urb->reject exists on 2.6.27, the poison/unpoison helpers ++ * did not though. The anchor poison does not exist so we cannot use them. ++ * ++ * USB anchor poising seems to exist to prevent future driver sumbissions ++ * of usb_anchor_urb() to an anchor marked as poisoned. For older kernels ++ * we cannot use that, so new usb_anchor_urb()s will be anchored. The down ++ * side to this should be submission of URBs will continue being anchored ++ * on an anchor instead of having them being rejected immediately when the ++ * driver realized we needed to stop. For ar9170 we poison URBs upon the ++ * ar9170 mac80211 stop callback(), don't think this should be so bad. ++ * It mean there is period of time in older kernels for which we continue ++ * to anchor new URBs to a known stopped anchor. We have two anchors ++ * (TX, and RX) ++ */ ++ ++#if 0 ++/** ++ * usb_poison_urb - reliably kill a transfer and prevent further use of an URB ++ * @urb: pointer to URB describing a previously submitted request, ++ * may be NULL ++ * ++ * This routine cancels an in-progress request. It is guaranteed that ++ * upon return all completion handlers will have finished and the URB ++ * will be totally idle and cannot be reused. These features make ++ * this an ideal way to stop I/O in a disconnect() callback. ++ * If the request has not already finished or been unlinked ++ * the completion handler will see urb->status == -ENOENT. ++ * ++ * After and while the routine runs, attempts to resubmit the URB will fail ++ * with error -EPERM. Thus even if the URB's completion handler always ++ * tries to resubmit, it will not succeed and the URB will become idle. ++ * ++ * This routine may not be used in an interrupt context (such as a bottom ++ * half or a completion handler), or when holding a spinlock, or in other ++ * situations where the caller can't schedule(). ++ * ++ * This routine should not be called by a driver after its disconnect ++ * method has returned. ++ */ ++void usb_poison_urb(struct urb *urb) ++{ ++ might_sleep(); ++ if (!(urb && urb->dev && urb->ep)) ++ return; ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28)) ++ spin_lock_irq(&usb_reject_lock); ++#endif ++ ++urb->reject; ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28)) ++ spin_unlock_irq(&usb_reject_lock); ++#endif ++ /* ++ * XXX: usb_hcd_unlink_urb() needs backporting... this is defined ++ * on usb hcd.c but urb.c gets access to it. That is, older kernels ++ * have usb_hcd_unlink_urb() but its not exported, nor can we ++ * re-implement it exactly. This essentially dequeues the urb from ++ * hw, we need to figure out a way to backport this. ++ */ ++ //usb_hcd_unlink_urb(urb, -ENOENT); ++ ++ wait_event(usb_kill_urb_queue, atomic_read(&urb->use_count) == 0); ++} ++EXPORT_SYMBOL_GPL(usb_poison_urb); ++#endif ++#endif /* CONFIG_USB */ ++ ++#if defined(CONFIG_PCMCIA) || defined(CONFIG_PCMCIA_MODULE) ++ ++#include ++struct pcmcia_cfg_mem { ++ tuple_t tuple; ++ cisparse_t parse; ++ u8 buf[256]; ++ cistpl_cftable_entry_t dflt; ++}; ++/** ++ * pcmcia_loop_config() - loop over configuration options ++ * @p_dev: the struct pcmcia_device which we need to loop for. ++ * @conf_check: function to call for each configuration option. ++ * It gets passed the struct pcmcia_device, the CIS data ++ * describing the configuration option, and private data ++ * being passed to pcmcia_loop_config() ++ * @priv_data: private data to be passed to the conf_check function. ++ * ++ * pcmcia_loop_config() loops over all configuration options, and calls ++ * the driver-specific conf_check() for each one, checking whether ++ * it is a valid one. Returns 0 on success or errorcode otherwise. ++ */ ++int pcmcia_loop_config(struct pcmcia_device *p_dev, ++ int (*conf_check) (struct pcmcia_device *p_dev, ++ cistpl_cftable_entry_t *cfg, ++ cistpl_cftable_entry_t *dflt, ++ unsigned int vcc, ++ void *priv_data), ++ void *priv_data) ++{ ++ struct pcmcia_cfg_mem *cfg_mem; ++ ++ tuple_t *tuple; ++ int ret; ++ unsigned int vcc; ++ ++ cfg_mem = kzalloc(sizeof(struct pcmcia_cfg_mem), GFP_KERNEL); ++ if (cfg_mem == NULL) ++ return -ENOMEM; ++ ++ /* get the current Vcc setting */ ++ vcc = p_dev->socket->socket.Vcc; ++ ++ tuple = &cfg_mem->tuple; ++ tuple->TupleData = cfg_mem->buf; ++ tuple->TupleDataMax = 255; ++ tuple->TupleOffset = 0; ++ tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY; ++ tuple->Attributes = 0; ++ ++ ret = pcmcia_get_first_tuple(p_dev, tuple); ++ while (!ret) { ++ cistpl_cftable_entry_t *cfg = &cfg_mem->parse.cftable_entry; ++ ++ if (pcmcia_get_tuple_data(p_dev, tuple)) ++ goto next_entry; ++ ++ if (pcmcia_parse_tuple(tuple, &cfg_mem->parse)) ++ goto next_entry; ++ ++ /* default values */ ++ p_dev->conf.ConfigIndex = cfg->index; ++ if (cfg->flags & CISTPL_CFTABLE_DEFAULT) ++ cfg_mem->dflt = *cfg; ++ ++ ret = conf_check(p_dev, cfg, &cfg_mem->dflt, vcc, priv_data); ++ if (!ret) ++ break; ++ ++next_entry: ++ ret = pcmcia_get_next_tuple(p_dev, tuple); ++ } ++ ++ return ret; ++} ++EXPORT_SYMBOL_GPL(pcmcia_loop_config); ++ ++#endif /* CONFIG_PCMCIA */ ++ ++#if defined(CONFIG_USB) || defined(CONFIG_USB_MODULE) ++ ++void usb_unpoison_urb(struct urb *urb) ++{ ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28)) ++ unsigned long flags; ++#endif ++ ++ if (!urb) ++ return; ++ ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28)) ++ spin_lock_irqsave(&usb_reject_lock, flags); ++#endif ++ --urb->reject; ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28)) ++ spin_unlock_irqrestore(&usb_reject_lock, flags); ++#endif ++} ++EXPORT_SYMBOL_GPL(usb_unpoison_urb); ++ ++ ++#if 0 ++/** ++ * usb_poison_anchored_urbs - cease all traffic from an anchor ++ * @anchor: anchor the requests are bound to ++ * ++ * this allows all outstanding URBs to be poisoned starting ++ * from the back of the queue. Newly added URBs will also be ++ * poisoned ++ * ++ * This routine should not be called by a driver after its disconnect ++ * method has returned. ++ */ ++void usb_poison_anchored_urbs(struct usb_anchor *anchor) ++{ ++ struct urb *victim; ++ ++ spin_lock_irq(&anchor->lock); ++ // anchor->poisoned = 1; /* XXX: Cannot backport */ ++ while (!list_empty(&anchor->urb_list)) { ++ victim = list_entry(anchor->urb_list.prev, struct urb, ++ anchor_list); ++ /* we must make sure the URB isn't freed before we kill it*/ ++ usb_get_urb(victim); ++ spin_unlock_irq(&anchor->lock); ++ /* this will unanchor the URB */ ++ usb_poison_urb(victim); ++ usb_put_urb(victim); ++ spin_lock_irq(&anchor->lock); ++ } ++ spin_unlock_irq(&anchor->lock); ++} ++EXPORT_SYMBOL_GPL(usb_poison_anchored_urbs); ++#endif ++ ++/** ++ * usb_anchor_empty - is an anchor empty ++ * @anchor: the anchor you want to query ++ * ++ * returns 1 if the anchor has no urbs associated with it ++ */ ++int usb_anchor_empty(struct usb_anchor *anchor) ++{ ++ return list_empty(&anchor->urb_list); ++} ++ ++EXPORT_SYMBOL_GPL(usb_anchor_empty); ++#endif /* CONFIG_USB */ ++#endif ++ ++void __iomem *pci_ioremap_bar(struct pci_dev *pdev, int bar) ++{ ++ /* ++ * Make sure the BAR is actually a memory resource, not an IO resource ++ */ ++ if (!(pci_resource_flags(pdev, bar) & IORESOURCE_MEM)) { ++ WARN_ON(1); ++ return NULL; ++ } ++ return ioremap_nocache(pci_resource_start(pdev, bar), ++ pci_resource_len(pdev, bar)); ++} ++EXPORT_SYMBOL_GPL(pci_ioremap_bar); ++ ++static unsigned long round_jiffies_common(unsigned long j, int cpu, ++ bool force_up) ++{ ++ int rem; ++ unsigned long original = j; ++ ++ /* ++ * We don't want all cpus firing their timers at once hitting the ++ * same lock or cachelines, so we skew each extra cpu with an extra ++ * 3 jiffies. This 3 jiffies came originally from the mm/ code which ++ * already did this. ++ * The skew is done by adding 3*cpunr, then round, then subtract this ++ * extra offset again. ++ */ ++ j += cpu * 3; ++ ++ rem = j % HZ; ++ ++ /* ++ * If the target jiffie is just after a whole second (which can happen ++ * due to delays of the timer irq, long irq off times etc etc) then ++ * we should round down to the whole second, not up. Use 1/4th second ++ * as cutoff for this rounding as an extreme upper bound for this. ++ * But never round down if @force_up is set. ++ */ ++ if (rem < HZ/4 && !force_up) /* round down */ ++ j = j - rem; ++ else /* round up */ ++ j = j - rem + HZ; ++ ++ /* now that we have rounded, subtract the extra skew again */ ++ j -= cpu * 3; ++ ++ if (j <= jiffies) /* rounding ate our timeout entirely; */ ++ return original; ++ return j; ++} ++ ++/** ++ * round_jiffies_up - function to round jiffies up to a full second ++ * @j: the time in (absolute) jiffies that should be rounded ++ * ++ * This is the same as round_jiffies() except that it will never ++ * round down. This is useful for timeouts for which the exact time ++ * of firing does not matter too much, as long as they don't fire too ++ * early. ++ */ ++unsigned long round_jiffies_up(unsigned long j) ++{ ++ return round_jiffies_common(j, raw_smp_processor_id(), true); ++} ++EXPORT_SYMBOL_GPL(round_jiffies_up); ++ ++void v2_6_28_skb_add_rx_frag(struct sk_buff *skb, int i, struct page *page, int off, ++ int size) ++{ ++ skb_fill_page_desc(skb, i, page, off, size); ++ skb->len += size; ++ skb->data_len += size; ++ skb->truesize += size; ++} ++EXPORT_SYMBOL_GPL(v2_6_28_skb_add_rx_frag); ++ ++void tty_write_unlock(struct tty_struct *tty) ++{ ++ mutex_unlock(&tty->atomic_write_lock); ++ wake_up_interruptible_poll(&tty->write_wait, POLLOUT); ++} ++ ++int tty_write_lock(struct tty_struct *tty, int ndelay) ++{ ++ if (!mutex_trylock(&tty->atomic_write_lock)) { ++ if (ndelay) ++ return -EAGAIN; ++ if (mutex_lock_interruptible(&tty->atomic_write_lock)) ++ return -ERESTARTSYS; ++ } ++ return 0; ++} ++ ++/** ++ * send_prio_char - send priority character ++ * ++ * Send a high priority character to the tty even if stopped ++ * ++ * Locking: none for xchar method, write ordering for write method. ++ */ ++ ++static int send_prio_char(struct tty_struct *tty, char ch) ++{ ++ int was_stopped = tty->stopped; ++ ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)) ++ if (tty->ops->send_xchar) { ++ tty->ops->send_xchar(tty, ch); ++#else ++ if (tty->driver->send_xchar) { ++ tty->driver->send_xchar(tty, ch); ++#endif ++ return 0; ++ } ++ ++ if (tty_write_lock(tty, 0) < 0) ++ return -ERESTARTSYS; ++ ++ if (was_stopped) ++ start_tty(tty); ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)) ++ tty->ops->write(tty, &ch, 1); ++#else ++ tty->driver->write(tty, &ch, 1); ++#endif ++ if (was_stopped) ++ stop_tty(tty); ++ tty_write_unlock(tty); ++ return 0; ++} ++ ++int n_tty_ioctl_helper(struct tty_struct *tty, struct file *file, ++ unsigned int cmd, unsigned long arg) ++{ ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)) ++ unsigned long flags; ++#endif ++ int retval; ++ ++ switch (cmd) { ++ case TCXONC: ++ retval = tty_check_change(tty); ++ if (retval) ++ return retval; ++ switch (arg) { ++ case TCOOFF: ++ if (!tty->flow_stopped) { ++ tty->flow_stopped = 1; ++ stop_tty(tty); ++ } ++ break; ++ case TCOON: ++ if (tty->flow_stopped) { ++ tty->flow_stopped = 0; ++ start_tty(tty); ++ } ++ break; ++ case TCIOFF: ++ if (STOP_CHAR(tty) != __DISABLED_CHAR) ++ return send_prio_char(tty, STOP_CHAR(tty)); ++ break; ++ case TCION: ++ if (START_CHAR(tty) != __DISABLED_CHAR) ++ return send_prio_char(tty, START_CHAR(tty)); ++ break; ++ default: ++ return -EINVAL; ++ } ++ return 0; ++ case TCFLSH: ++ return tty_perform_flush(tty, arg); ++ case TIOCPKT: ++ { ++ int pktmode; ++ ++ if (tty->driver->type != TTY_DRIVER_TYPE_PTY || ++ tty->driver->subtype != PTY_TYPE_MASTER) ++ return -ENOTTY; ++ if (get_user(pktmode, (int __user *) arg)) ++ return -EFAULT; ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)) ++ spin_lock_irqsave(&tty->ctrl_lock, flags); ++#endif ++ if (pktmode) { ++ if (!tty->packet) { ++ tty->packet = 1; ++ tty->link->ctrl_status = 0; ++ } ++ } else ++ tty->packet = 0; ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)) ++ spin_unlock_irqrestore(&tty->ctrl_lock, flags); ++#endif ++ return 0; ++ } ++ default: ++ /* Try the mode commands */ ++ return tty_mode_ioctl(tty, file, cmd, arg); ++ } ++} ++EXPORT_SYMBOL_GPL(n_tty_ioctl_helper); ++ ++/** ++ * pci_wake_from_d3 - enable/disable device to wake up from D3_hot or D3_cold ++ * @dev: PCI device to prepare ++ * @enable: True to enable wake-up event generation; false to disable ++ * ++ * Many drivers want the device to wake up the system from D3_hot or D3_cold ++ * and this function allows them to set that up cleanly - pci_enable_wake() ++ * should not be called twice in a row to enable wake-up due to PCI PM vs ACPI ++ * ordering constraints. ++ * ++ * This function only returns error code if the device is not capable of ++ * generating PME# from both D3_hot and D3_cold, and the platform is unable to ++ * enable wake-up power for it. ++ */ ++int pci_wake_from_d3(struct pci_dev *dev, bool enable) ++{ ++ return pci_pme_capable(dev, PCI_D3cold) ? ++ pci_enable_wake(dev, PCI_D3cold, enable) : ++ pci_enable_wake(dev, PCI_D3hot, enable); ++} ++EXPORT_SYMBOL_GPL(pci_wake_from_d3); ++ diff --cc compat/compat/compat-2.6.29.c index 000000000000,000000000000..1beb718dc795 new file mode 100644 --- /dev/null +++ b/compat/compat/compat-2.6.29.c @@@ -1,0 -1,0 +1,166 @@@ ++/* ++ * Copyright 2007-2010 Luis R. Rodriguez ++ * ++ * 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 ++#include ++#include ++ ++/* ++ * 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 */ ++ diff --cc compat/compat/compat-2.6.32.c index 000000000000,000000000000..b5a66a869e88 new file mode 100644 --- /dev/null +++ b/compat/compat/compat-2.6.32.c @@@ -1,0 -1,0 +1,216 @@@ ++/* ++ * Copyright 2007 Luis R. Rodriguez ++ * ++ * 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 ++#include ++ ++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*/ ++ diff --cc compat/compat/compat-2.6.33.c index 000000000000,000000000000..f584b859ff1e new file mode 100644 --- /dev/null +++ b/compat/compat/compat-2.6.33.c @@@ -1,0 -1,0 +1,230 @@@ ++/* ++ * Copyright 2009 Hauke Mehrtens ++ * ++ * 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 ++#include ++#include ++#include ++#include ++ ++#ifdef CONFIG_USB_SUSPEND ++/** ++ * usb_autopm_get_interface_no_resume - increment a USB interface's PM-usage counter ++ * @intf: the usb_interface whose counter should be incremented ++ * ++ * This routine increments @intf's usage counter but does not carry out an ++ * autoresume. ++ * ++ * This routine can run in atomic context. ++ */ ++void usb_autopm_get_interface_no_resume(struct usb_interface *intf) ++{ ++ struct usb_device *udev = interface_to_usbdev(intf); ++ ++ usb_mark_last_busy(udev); ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32)) ++ atomic_inc(&intf->pm_usage_cnt); ++#else ++ intf->pm_usage_cnt++; ++#endif ++ pm_runtime_get_noresume(&intf->dev); ++} ++EXPORT_SYMBOL_GPL(usb_autopm_get_interface_no_resume); ++ ++/** ++ * usb_autopm_put_interface_no_suspend - decrement a USB interface's PM-usage counter ++ * @intf: the usb_interface whose counter should be decremented ++ * ++ * This routine decrements @intf's usage counter but does not carry out an ++ * autosuspend. ++ * ++ * This routine can run in atomic context. ++ */ ++void usb_autopm_put_interface_no_suspend(struct usb_interface *intf) ++{ ++ struct usb_device *udev = interface_to_usbdev(intf); ++ ++ usb_mark_last_busy(udev); ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32)) ++ atomic_dec(&intf->pm_usage_cnt); ++#else ++ intf->pm_usage_cnt--; ++#endif ++ pm_runtime_put_noidle(&intf->dev); ++} ++EXPORT_SYMBOL_GPL(usb_autopm_put_interface_no_suspend); ++#endif /* CONFIG_USB_SUSPEND */ ++ ++#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 */ ++ ++/** ++ * platform_device_register_data ++ * @parent: parent device for the device we're adding ++ * @name: base name of the device we're adding ++ * @id: instance id ++ * @data: platform specific data for this platform device ++ * @size: size of platform specific data ++ * ++ * This function creates a simple platform device that requires minimal ++ * resource and memory management. Canned release function freeing memory ++ * allocated for the device allows drivers using such devices to be ++ * unloaded without waiting for the last reference to the device to be ++ * dropped. ++ */ ++struct platform_device *platform_device_register_data( ++ struct device *parent, ++ const char *name, int id, ++ const void *data, size_t size) ++{ ++ struct platform_device *pdev; ++ int retval; ++ ++ pdev = platform_device_alloc(name, id); ++ if (!pdev) { ++ retval = -ENOMEM; ++ goto error; ++ } ++ ++ pdev->dev.parent = parent; ++ ++ if (size) { ++ retval = platform_device_add_data(pdev, data, size); ++ if (retval) ++ goto error; ++ } ++ ++ retval = platform_device_add(pdev); ++ if (retval) ++ goto error; ++ ++ return pdev; ++ ++error: ++ platform_device_put(pdev); ++ return ERR_PTR(retval); ++} ++EXPORT_SYMBOL_GPL(platform_device_register_data); diff --cc compat/compat/compat-2.6.34.c index 000000000000,000000000000..4b23c81799e3 new file mode 100644 --- /dev/null +++ b/compat/compat/compat-2.6.34.c @@@ -1,0 -1,0 +1,85 @@@ ++/* ++ * Copyright 2012 Luis R. Rodriguez ++ * ++ * 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.34. ++ */ ++ ++#include ++ ++#include "compat-2.6.34.h" ++ ++static mmc_pm_flag_t backport_mmc_pm_flags; ++ ++void backport_init_mmc_pm_flags(void) ++{ ++ backport_mmc_pm_flags = 0; ++} ++ ++mmc_pm_flag_t sdio_get_host_pm_caps(struct sdio_func *func) ++{ ++ return backport_mmc_pm_flags; ++} ++ ++int sdio_set_host_pm_flags(struct sdio_func *func, mmc_pm_flag_t flags) ++{ ++ return -EINVAL; ++} ++ ++/** ++ * seq_hlist_start - start an iteration of a hlist ++ * @head: the head of the hlist ++ * @pos: the start position of the sequence ++ * ++ * Called at seq_file->op->start(). ++ */ ++struct hlist_node *seq_hlist_start(struct hlist_head *head, loff_t pos) ++{ ++ struct hlist_node *node; ++ ++ hlist_for_each(node, head) ++ if (pos-- == 0) ++ return node; ++ return NULL; ++} ++ ++/** ++ * seq_hlist_start_head - start an iteration of a hlist ++ * @head: the head of the hlist ++ * @pos: the start position of the sequence ++ * ++ * Called at seq_file->op->start(). Call this function if you want to ++ * print a header at the top of the output. ++ */ ++struct hlist_node *seq_hlist_start_head(struct hlist_head *head, loff_t pos) ++{ ++ if (!pos) ++ return SEQ_START_TOKEN; ++ ++ return seq_hlist_start(head, pos - 1); ++} ++EXPORT_SYMBOL_GPL(seq_hlist_start_head); ++ ++/** ++ * seq_hlist_next - move to the next position of the hlist ++ * @v: the current iterator ++ * @head: the head of the hlist ++ * @ppos: the current position ++ * ++ * Called at seq_file->op->next(). ++ */ ++struct hlist_node *seq_hlist_next(void *v, struct hlist_head *head, ++ loff_t *ppos) ++{ ++ struct hlist_node *node = v; ++ ++ ++*ppos; ++ if (v == SEQ_START_TOKEN) ++ return head->first; ++ else ++ return node->next; ++} ++EXPORT_SYMBOL_GPL(seq_hlist_next); diff --cc compat/compat/compat-2.6.34.h index 000000000000,000000000000..b36b441a2a82 new file mode 100644 --- /dev/null +++ b/compat/compat/compat-2.6.34.h @@@ -1,0 -1,0 +1,20 @@@ ++#ifndef LINUX_26_34_COMPAT_PRIVATE_H ++#define LINUX_26_34_COMPAT_PRIVATE_H ++ ++#include ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,34)) ++ ++#include ++ ++void backport_init_mmc_pm_flags(void); ++ ++#else /* Kernels >= 2.6.34 */ ++ ++static inline void backport_init_mmc_pm_flags(void) ++{ ++} ++ ++#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,34)) */ ++ ++#endif /* LINUX_26_34_COMPAT_PRIVATE_H */ diff --cc compat/compat/compat-2.6.35.c index 000000000000,000000000000..20fee85337f6 new file mode 100644 --- /dev/null +++ b/compat/compat/compat-2.6.35.c @@@ -1,0 -1,0 +1,125 @@@ ++/* ++ * Copyright 2010 Kshitij Kulshreshtha ++ * Copyright 2012 Luis R. Rodriguez ++ * ++ * 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 ++#include ++ ++#ifdef CONFIG_RPS ++int netif_set_real_num_rx_queues(struct net_device *dev, unsigned int rxq) ++{ ++ int rc; ++ ++ /* we can't update the sysfs object for older kernels */ ++ if (dev->reg_state == NETREG_REGISTERED) ++ return -EINVAL; ++ dev->num_rx_queues = rxq; ++ return 0; ++} ++#endif ++ ++/* ++ * Routine to help set real_num_tx_queues. To avoid skbs mapped to queues ++ * greater then real_num_tx_queues stale skbs on the qdisc must be flushed. ++ */ ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)) ++int netif_set_real_num_tx_queues(struct net_device *dev, unsigned int txq) ++{ ++ unsigned int real_num = dev->real_num_tx_queues; ++ ++ if (unlikely(txq > dev->num_tx_queues)) ++ return -EINVAL; ++ else if (txq > real_num) ++ dev->real_num_tx_queues = txq; ++ else if (txq < real_num) { ++ dev->real_num_tx_queues = txq; ++ qdisc_reset_all_tx_gt(dev, txq); ++ } ++ return 0; ++} ++#else ++int netif_set_real_num_tx_queues(struct net_device *dev, unsigned int txq) ++{ ++ dev->egress_subqueue_count = txq; ++ /* XXX: consider qdisc reset for older kernels */ ++ return 0; ++} ++#endif ++EXPORT_SYMBOL_GPL(netif_set_real_num_tx_queues); ++ ++/** ++ * 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 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(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); ++ ++/** ++ * simple_write_to_buffer - copy data from user space to the buffer ++ * @to: the buffer to write to ++ * @available: the size of the buffer ++ * @ppos: the current position in the buffer ++ * @from: the user space buffer to read from ++ * @count: the maximum number of bytes to read ++ * ++ * The simple_write_to_buffer() function reads up to @count bytes from the user ++ * space address starting at @from into the buffer @to at offset @ppos. ++ * ++ * On success, the number of bytes written is returned and the offset @ppos is ++ * advanced by this number, or negative value is returned on error. ++ **/ ++ssize_t simple_write_to_buffer(void *to, size_t available, loff_t *ppos, ++ const void __user *from, size_t count) ++{ ++ loff_t pos = *ppos; ++ size_t res; ++ ++ if (pos < 0) ++ return -EINVAL; ++ if (pos >= available || !count) ++ return 0; ++ if (count > available - pos) ++ count = available - pos; ++ res = copy_from_user(to + pos, from, count); ++ if (res == count) ++ return -EFAULT; ++ count -= res; ++ *ppos = pos + count; ++ return count; ++} ++EXPORT_SYMBOL_GPL(simple_write_to_buffer); diff --cc compat/compat/compat-2.6.36.c index 000000000000,000000000000..9295895b9379 new file mode 100644 --- /dev/null +++ b/compat/compat/compat-2.6.36.c @@@ -1,0 -1,0 +1,185 @@@ ++/* ++ * Copyright 2010 Hauke Mehrtens ++ * ++ * 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 ++#include ++ ++#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 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(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 *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(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 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(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 schedule_work(struct work_struct *work) ++{ ++ return queue_work(system_wq, work); ++} ++EXPORT_SYMBOL_GPL(schedule_work); ++ ++int 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(schedule_work_on); ++ ++int schedule_delayed_work(struct delayed_work *dwork, ++ unsigned long delay) ++{ ++ return queue_delayed_work(system_wq, dwork, delay); ++} ++EXPORT_SYMBOL_GPL(schedule_delayed_work); ++ ++int 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(schedule_delayed_work_on); ++ ++void 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(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 backport_system_workqueue_create(void) ++{ ++ 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 backport_system_workqueue_destroy(void) ++{ ++ destroy_workqueue(system_wq); ++ destroy_workqueue(system_long_wq); ++ destroy_workqueue(system_nrt_wq); ++} diff --cc compat/compat/compat-2.6.37.c index 000000000000,000000000000..9f722a6269b3 new file mode 100644 --- /dev/null +++ b/compat/compat/compat-2.6.37.c @@@ -1,0 -1,0 +1,358 @@@ ++/* ++ * Copyright 2010 Hauke Mehrtens ++ * ++ * 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 ++#include ++#include ++#include ++#include ++ ++#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 *vzalloc(unsigned long size) ++{ ++ void *buf; ++ buf = vmalloc(size); ++ if (buf) ++ memset(buf, 0, size); ++ return buf; ++} ++EXPORT_SYMBOL_GPL(vzalloc); ++ ++#endif diff --cc compat/compat/compat-2.6.38.c index 000000000000,000000000000..0074ac625223 new file mode 100644 --- /dev/null +++ b/compat/compat/compat-2.6.38.c @@@ -1,0 -1,0 +1,50 @@@ ++/* ++ * Copyright 2010 Hauke Mehrtens ++ * ++ * 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 ++#include ++#include ++ ++/** ++ * 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); ++ diff --cc compat/compat/compat-2.6.39.c index 000000000000,000000000000..5bb932218d15 new file mode 100644 --- /dev/null +++ b/compat/compat/compat-2.6.39.c @@@ -1,0 -1,0 +1,114 @@@ ++/* ++ * Copyright 2011 Hauke Mehrtens ++ * ++ * 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 ++#include ++#include ++ ++#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)) */ ++ diff --cc compat/compat/compat-3.0.c index 000000000000,000000000000..e84137301d4f new file mode 100644 --- /dev/null +++ b/compat/compat/compat-3.0.c @@@ -1,0 -1,0 +1,85 @@@ ++/* ++ * Copyright 2011 Hauke Mehrtens ++ * Copyright 2011 Alexey Dobriyan ++ * ++ * 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 ++#include ++ ++/* This pulls-in a lot of non-exported symbol backports ++ * on kernels older than 2.6.32. There's no harm for not ++ * making this available on kernels < 2.6.32. */ ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32)) ++#include ++ ++/* This backports: ++ * ++ * commit d9d90e5eb70e09903dadff42099b6c948f814050 ++ * Author: Hugh Dickins ++ * Date: Mon Jun 27 16:18:04 2011 -0700 ++ * ++ * tmpfs: add shmem_read_mapping_page_gfp ++ */ ++ ++struct page *shmem_read_mapping_page_gfp(struct address_space *mapping, ++ pgoff_t index, gfp_t gfp) ++{ ++ return read_cache_page_gfp(mapping, index, gfp); ++} ++EXPORT_SYMBOL_GPL(shmem_read_mapping_page_gfp); ++#endif ++ ++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); diff --cc compat/compat/compat-3.1.c index 000000000000,000000000000..cb5d596a6881 new file mode 100644 --- /dev/null +++ b/compat/compat/compat-3.1.c @@@ -1,0 -1,0 +1,107 @@@ ++/* ++ * Copyright 2012 Hauke Mehrtens ++ * ++ * 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.1. ++ */ ++ ++#include ++#include ++ ++/* This backports: ++ * commit 3d73710880afa3d61cf57b5d4eb192e812eb7e4f ++ * Author: Jesse Barnes ++ * Date: Tue Jun 28 10:59:12 2011 -0700 ++ * ++ * cpufreq: expose a cpufreq_quick_get_max routine ++ */ ++#ifdef CONFIG_CPU_FREQ ++unsigned int cpufreq_quick_get_max(unsigned int cpu) ++{ ++ struct cpufreq_policy *policy = cpufreq_cpu_get(cpu); ++ unsigned int ret_freq = 0; ++ ++ if (policy) { ++ ret_freq = policy->max; ++ cpufreq_cpu_put(policy); ++ } ++ ++ return ret_freq; ++} ++EXPORT_SYMBOL_GPL(cpufreq_quick_get_max); ++#endif ++ ++static DEFINE_SPINLOCK(compat_simple_ida_lock); ++ ++/** ++ * ida_simple_get - get a new id. ++ * @ida: the (initialized) ida. ++ * @start: the minimum id (inclusive, < 0x8000000) ++ * @end: the maximum id (exclusive, < 0x8000000 or 0) ++ * @gfp_mask: memory allocation flags ++ * ++ * Allocates an id in the range start <= id < end, or returns -ENOSPC. ++ * On memory allocation failure, returns -ENOMEM. ++ * ++ * Use ida_simple_remove() to get rid of an id. ++ */ ++int ida_simple_get(struct ida *ida, unsigned int start, unsigned int end, ++ gfp_t gfp_mask) ++{ ++ int ret, id; ++ unsigned int max; ++ unsigned long flags; ++ ++ BUG_ON((int)start < 0); ++ BUG_ON((int)end < 0); ++ ++ if (end == 0) ++ max = 0x80000000; ++ else { ++ BUG_ON(end < start); ++ max = end - 1; ++ } ++ ++again: ++ if (!ida_pre_get(ida, gfp_mask)) ++ return -ENOMEM; ++ ++ spin_lock_irqsave(&compat_simple_ida_lock, flags); ++ ret = ida_get_new_above(ida, start, &id); ++ if (!ret) { ++ if (id > max) { ++ ida_remove(ida, id); ++ ret = -ENOSPC; ++ } else { ++ ret = id; ++ } ++ } ++ spin_unlock_irqrestore(&compat_simple_ida_lock, flags); ++ ++ if (unlikely(ret == -EAGAIN)) ++ goto again; ++ ++ return ret; ++} ++EXPORT_SYMBOL_GPL(ida_simple_get); ++ ++/** ++ * ida_simple_remove - remove an allocated id. ++ * @ida: the (initialized) ida. ++ * @id: the id returned by ida_simple_get. ++ */ ++void ida_simple_remove(struct ida *ida, unsigned int id) ++{ ++ unsigned long flags; ++ ++ BUG_ON((int)id < 0); ++ spin_lock_irqsave(&compat_simple_ida_lock, flags); ++ ida_remove(ida, id); ++ spin_unlock_irqrestore(&compat_simple_ida_lock, flags); ++} ++EXPORT_SYMBOL_GPL(ida_simple_remove); ++/* source lib/idr.c */ ++ diff --cc compat/compat/compat-3.2.c index 000000000000,000000000000..55ae6af0f935 new file mode 100644 --- /dev/null +++ b/compat/compat/compat-3.2.c @@@ -1,0 -1,0 +1,34 @@@ ++/* ++ * Copyright 2012 Luis R. Rodriguez ++ * ++ * 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 ++#include ++ ++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); diff --cc compat/compat/compat-3.3.c index 000000000000,000000000000..8489344614a4 new file mode 100644 --- /dev/null +++ b/compat/compat/compat-3.3.c @@@ -1,0 -1,0 +1,173 @@@ ++/* ++ * Copyright 2012 Luis R. Rodriguez ++ * ++ * 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 ++#include ++#include ++#include ++#include ++#include ++ ++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); diff --cc compat/compat/compat-3.4.c index 000000000000,000000000000..f8512e454e63 new file mode 100644 --- /dev/null +++ b/compat/compat/compat-3.4.c @@@ -1,0 -1,0 +1,491 @@@ ++/* ++ * Copyright 2012 Luis R. Rodriguez ++ * ++ * 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.4. ++ */ ++ ++#include ++#include ++#include ++ ++/* __wake_up_common was declared as part of the wait.h until ++ * 2.6.31 in which they made it private to the scheduler. Prefix it with ++ * compat to avoid double declaration issues. ++ */ ++static void compat_wake_up_common(wait_queue_head_t *q, unsigned int mode, ++ int nr_exclusive, int wake_flags, void *key) ++{ ++ wait_queue_t *curr, *next; ++ ++ list_for_each_entry_safe(curr, next, &q->task_list, task_list) { ++ unsigned flags = curr->flags; ++ ++ if (curr->func(curr, mode, wake_flags, key) && ++ (flags & WQ_FLAG_EXCLUSIVE) && !--nr_exclusive) ++ break; ++ } ++} ++ ++/* The last 'nr' parameter was added to the __wake_up_locked() function ++ * in 3.4 kernel. Define a new one prefixed with compat_ for the new API. ++ */ ++void compat_wake_up_locked(wait_queue_head_t *q, unsigned int mode, int nr) ++{ ++ compat_wake_up_common(q, mode, nr, 0, NULL); ++} ++EXPORT_SYMBOL_GPL(compat_wake_up_locked); ++ ++ ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34)) ++#include ++#include ++#include ++ ++#define setsda(adap, val) adap->setsda(adap->data, val) ++#define setscl(adap, val) adap->setscl(adap->data, val) ++#define getsda(adap) adap->getsda(adap->data) ++#define getscl(adap) adap->getscl(adap->data) ++ ++#define bit_dbg(level, dev, format, args...) \ ++ do {} while (0) ++ ++static inline void sdalo(struct i2c_algo_bit_data *adap) ++{ ++ setsda(adap, 0); ++ udelay((adap->udelay + 1) / 2); ++} ++ ++static inline void sdahi(struct i2c_algo_bit_data *adap) ++{ ++ setsda(adap, 1); ++ udelay((adap->udelay + 1) / 2); ++} ++ ++static inline void scllo(struct i2c_algo_bit_data *adap) ++{ ++ setscl(adap, 0); ++ udelay(adap->udelay / 2); ++} ++ ++static int sclhi(struct i2c_algo_bit_data *adap) ++{ ++ unsigned long start; ++ ++ setscl(adap, 1); ++ ++ /* Not all adapters have scl sense line... */ ++ if (!adap->getscl) ++ goto done; ++ ++ start = jiffies; ++ while (!getscl(adap)) { ++ /* This hw knows how to read the clock line, so we wait ++ * until it actually gets high. This is safer as some ++ * chips may hold it low ("clock stretching") while they ++ * are processing data internally. ++ */ ++ if (time_after(jiffies, start + adap->timeout)) { ++ /* Test one last time, as we may have been preempted ++ * between last check and timeout test. ++ */ ++ if (getscl(adap)) ++ break; ++ return -ETIMEDOUT; ++ } ++ cpu_relax(); ++ } ++#ifdef DEBUG ++ if (jiffies != start && i2c_debug >= 3) ++ pr_debug("i2c-algo-bit: needed %ld jiffies for SCL to go " ++ "high\n", jiffies - start); ++#endif ++ ++done: ++ udelay(adap->udelay); ++ return 0; ++} ++ ++static void i2c_start(struct i2c_algo_bit_data *adap) ++{ ++ /* assert: scl, sda are high */ ++ setsda(adap, 0); ++ udelay(adap->udelay); ++ scllo(adap); ++} ++ ++static void i2c_repstart(struct i2c_algo_bit_data *adap) ++{ ++ /* assert: scl is low */ ++ sdahi(adap); ++ sclhi(adap); ++ setsda(adap, 0); ++ udelay(adap->udelay); ++ scllo(adap); ++} ++ ++ ++static void i2c_stop(struct i2c_algo_bit_data *adap) ++{ ++ /* assert: scl is low */ ++ sdalo(adap); ++ sclhi(adap); ++ setsda(adap, 1); ++ udelay(adap->udelay); ++} ++ ++static int i2c_outb(struct i2c_adapter *i2c_adap, unsigned char c) ++{ ++ int i; ++ int sb; ++ int ack; ++ struct i2c_algo_bit_data *adap = i2c_adap->algo_data; ++ ++ /* assert: scl is low */ ++ for (i = 7; i >= 0; i--) { ++ sb = (c >> i) & 1; ++ setsda(adap, sb); ++ udelay((adap->udelay + 1) / 2); ++ if (sclhi(adap) < 0) { /* timed out */ ++ bit_dbg(1, &i2c_adap->dev, "i2c_outb: 0x%02x, " ++ "timeout at bit #%d\n", (int)c, i); ++ return -ETIMEDOUT; ++ } ++ /* FIXME do arbitration here: ++ * if (sb && !getsda(adap)) -> ouch! Get out of here. ++ * ++ * Report a unique code, so higher level code can retry ++ * the whole (combined) message and *NOT* issue STOP. ++ */ ++ scllo(adap); ++ } ++ sdahi(adap); ++ if (sclhi(adap) < 0) { /* timeout */ ++ bit_dbg(1, &i2c_adap->dev, "i2c_outb: 0x%02x, " ++ "timeout at ack\n", (int)c); ++ return -ETIMEDOUT; ++ } ++ ++ /* read ack: SDA should be pulled down by slave, or it may ++ * NAK (usually to report problems with the data we wrote). ++ */ ++ ack = !getsda(adap); /* ack: sda is pulled low -> success */ ++ bit_dbg(2, &i2c_adap->dev, "i2c_outb: 0x%02x %s\n", (int)c, ++ ack ? "A" : "NA"); ++ ++ scllo(adap); ++ return ack; ++ /* assert: scl is low (sda undef) */ ++} ++ ++static int i2c_inb(struct i2c_adapter *i2c_adap) ++{ ++ /* read byte via i2c port, without start/stop sequence */ ++ /* acknowledge is sent in i2c_read. */ ++ int i; ++ unsigned char indata = 0; ++ struct i2c_algo_bit_data *adap = i2c_adap->algo_data; ++ ++ /* assert: scl is low */ ++ sdahi(adap); ++ for (i = 0; i < 8; i++) { ++ if (sclhi(adap) < 0) { /* timeout */ ++ bit_dbg(1, &i2c_adap->dev, "i2c_inb: timeout at bit " ++ "#%d\n", 7 - i); ++ return -ETIMEDOUT; ++ } ++ indata *= 2; ++ if (getsda(adap)) ++ indata |= 0x01; ++ setscl(adap, 0); ++ udelay(i == 7 ? adap->udelay / 2 : adap->udelay); ++ } ++ /* assert: scl is low */ ++ return indata; ++} ++ ++static int try_address(struct i2c_adapter *i2c_adap, ++ unsigned char addr, int retries) ++{ ++ struct i2c_algo_bit_data *adap = i2c_adap->algo_data; ++ int i, ret = 0; ++ ++ for (i = 0; i <= retries; i++) { ++ ret = i2c_outb(i2c_adap, addr); ++ if (ret == 1 || i == retries) ++ break; ++ bit_dbg(3, &i2c_adap->dev, "emitting stop condition\n"); ++ i2c_stop(adap); ++ udelay(adap->udelay); ++ yield(); ++ bit_dbg(3, &i2c_adap->dev, "emitting start condition\n"); ++ i2c_start(adap); ++ } ++ if (i && ret) ++ bit_dbg(1, &i2c_adap->dev, "Used %d tries to %s client at " ++ "0x%02x: %s\n", i + 1, ++ addr & 1 ? "read from" : "write to", addr >> 1, ++ ret == 1 ? "success" : "failed, timeout?"); ++ return ret; ++} ++ ++static int bit_doAddress(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) ++{ ++ unsigned short flags = msg->flags; ++ unsigned short nak_ok = msg->flags & I2C_M_IGNORE_NAK; ++ struct i2c_algo_bit_data *adap = i2c_adap->algo_data; ++ ++ unsigned char addr; ++ int ret, retries; ++ ++ retries = nak_ok ? 0 : i2c_adap->retries; ++ ++ if (flags & I2C_M_TEN) { ++ /* a ten bit address */ ++ addr = 0xf0 | ((msg->addr >> 7) & 0x06); ++ bit_dbg(2, &i2c_adap->dev, "addr0: %d\n", addr); ++ /* try extended address code...*/ ++ ret = try_address(i2c_adap, addr, retries); ++ if ((ret != 1) && !nak_ok) { ++ dev_err(&i2c_adap->dev, ++ "died at extended address code\n"); ++ return -ENXIO; ++ } ++ /* the remaining 8 bit address */ ++ ret = i2c_outb(i2c_adap, msg->addr & 0xff); ++ if ((ret != 1) && !nak_ok) { ++ /* the chip did not ack / xmission error occurred */ ++ dev_err(&i2c_adap->dev, "died at 2nd address code\n"); ++ return -ENXIO; ++ } ++ if (flags & I2C_M_RD) { ++ bit_dbg(3, &i2c_adap->dev, "emitting repeated " ++ "start condition\n"); ++ i2c_repstart(adap); ++ /* okay, now switch into reading mode */ ++ addr |= 0x01; ++ ret = try_address(i2c_adap, addr, retries); ++ if ((ret != 1) && !nak_ok) { ++ dev_err(&i2c_adap->dev, ++ "died at repeated address code\n"); ++ return -EIO; ++ } ++ } ++ } else { /* normal 7bit address */ ++ addr = msg->addr << 1; ++ if (flags & I2C_M_RD) ++ addr |= 1; ++ if (flags & I2C_M_REV_DIR_ADDR) ++ addr ^= 1; ++ ret = try_address(i2c_adap, addr, retries); ++ if ((ret != 1) && !nak_ok) ++ return -ENXIO; ++ } ++ ++ return 0; ++} ++ ++static int sendbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) ++{ ++ const unsigned char *temp = msg->buf; ++ int count = msg->len; ++ unsigned short nak_ok = msg->flags & I2C_M_IGNORE_NAK; ++ int retval; ++ int wrcount = 0; ++ ++ while (count > 0) { ++ retval = i2c_outb(i2c_adap, *temp); ++ ++ /* OK/ACK; or ignored NAK */ ++ if ((retval > 0) || (nak_ok && (retval == 0))) { ++ count--; ++ temp++; ++ wrcount++; ++ ++ /* A slave NAKing the master means the slave didn't like ++ * something about the data it saw. For example, maybe ++ * the SMBus PEC was wrong. ++ */ ++ } else if (retval == 0) { ++ dev_err(&i2c_adap->dev, "sendbytes: NAK bailout.\n"); ++ return -EIO; ++ ++ /* Timeout; or (someday) lost arbitration ++ * ++ * FIXME Lost ARB implies retrying the transaction from ++ * the first message, after the "winning" master issues ++ * its STOP. As a rule, upper layer code has no reason ++ * to know or care about this ... it is *NOT* an error. ++ */ ++ } else { ++ dev_err(&i2c_adap->dev, "sendbytes: error %d\n", ++ retval); ++ return retval; ++ } ++ } ++ return wrcount; ++} ++ ++static int acknak(struct i2c_adapter *i2c_adap, int is_ack) ++{ ++ struct i2c_algo_bit_data *adap = i2c_adap->algo_data; ++ ++ /* assert: sda is high */ ++ if (is_ack) /* send ack */ ++ setsda(adap, 0); ++ udelay((adap->udelay + 1) / 2); ++ if (sclhi(adap) < 0) { /* timeout */ ++ dev_err(&i2c_adap->dev, "readbytes: ack/nak timeout\n"); ++ return -ETIMEDOUT; ++ } ++ scllo(adap); ++ return 0; ++} ++ ++static int readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) ++{ ++ int inval; ++ int rdcount = 0; /* counts bytes read */ ++ unsigned char *temp = msg->buf; ++ int count = msg->len; ++ const unsigned flags = msg->flags; ++ ++ while (count > 0) { ++ inval = i2c_inb(i2c_adap); ++ if (inval >= 0) { ++ *temp = inval; ++ rdcount++; ++ } else { /* read timed out */ ++ break; ++ } ++ ++ temp++; ++ count--; ++ ++ /* Some SMBus transactions require that we receive the ++ transaction length as the first read byte. */ ++ if (rdcount == 1 && (flags & I2C_M_RECV_LEN)) { ++ if (inval <= 0 || inval > I2C_SMBUS_BLOCK_MAX) { ++ if (!(flags & I2C_M_NO_RD_ACK)) ++ acknak(i2c_adap, 0); ++ dev_err(&i2c_adap->dev, "readbytes: invalid " ++ "block length (%d)\n", inval); ++ return -EPROTO; ++ } ++ /* The original count value accounts for the extra ++ bytes, that is, either 1 for a regular transaction, ++ or 2 for a PEC transaction. */ ++ count += inval; ++ msg->len += inval; ++ } ++ ++ bit_dbg(2, &i2c_adap->dev, "readbytes: 0x%02x %s\n", ++ inval, ++ (flags & I2C_M_NO_RD_ACK) ++ ? "(no ack/nak)" ++ : (count ? "A" : "NA")); ++ ++ if (!(flags & I2C_M_NO_RD_ACK)) { ++ inval = acknak(i2c_adap, count); ++ if (inval < 0) ++ return inval; ++ } ++ } ++ return rdcount; ++} ++ ++ ++static u32 bit_func(struct i2c_adapter *adap) ++{ ++ return I2C_FUNC_I2C | I2C_FUNC_NOSTART | I2C_FUNC_SMBUS_EMUL | ++ I2C_FUNC_SMBUS_READ_BLOCK_DATA | ++ I2C_FUNC_SMBUS_BLOCK_PROC_CALL | ++ I2C_FUNC_10BIT_ADDR | I2C_FUNC_PROTOCOL_MANGLING; ++} ++ ++static int bit_xfer(struct i2c_adapter *i2c_adap, ++ struct i2c_msg msgs[], int num) ++{ ++ struct i2c_msg *pmsg; ++ struct i2c_algo_bit_data *adap = i2c_adap->algo_data; ++ int i, ret; ++ unsigned short nak_ok; ++ ++ if (adap->pre_xfer) { ++ ret = adap->pre_xfer(i2c_adap); ++ if (ret < 0) ++ return ret; ++ } ++ ++ bit_dbg(3, &i2c_adap->dev, "emitting start condition\n"); ++ i2c_start(adap); ++ for (i = 0; i < num; i++) { ++ pmsg = &msgs[i]; ++ nak_ok = pmsg->flags & I2C_M_IGNORE_NAK; ++ if (!(pmsg->flags & I2C_M_NOSTART)) { ++ if (i) { ++ bit_dbg(3, &i2c_adap->dev, "emitting " ++ "repeated start condition\n"); ++ i2c_repstart(adap); ++ } ++ ret = bit_doAddress(i2c_adap, pmsg); ++ if ((ret != 0) && !nak_ok) { ++ bit_dbg(1, &i2c_adap->dev, "NAK from " ++ "device addr 0x%02x msg #%d\n", ++ msgs[i].addr, i); ++ goto bailout; ++ } ++ } ++ if (pmsg->flags & I2C_M_RD) { ++ /* read bytes into buffer*/ ++ ret = readbytes(i2c_adap, pmsg); ++ if (ret >= 1) ++ bit_dbg(2, &i2c_adap->dev, "read %d byte%s\n", ++ ret, ret == 1 ? "" : "s"); ++ if (ret < pmsg->len) { ++ if (ret >= 0) ++ ret = -EIO; ++ goto bailout; ++ } ++ } else { ++ /* write bytes from buffer */ ++ ret = sendbytes(i2c_adap, pmsg); ++ if (ret >= 1) ++ bit_dbg(2, &i2c_adap->dev, "wrote %d byte%s\n", ++ ret, ret == 1 ? "" : "s"); ++ if (ret < pmsg->len) { ++ if (ret >= 0) ++ ret = -EIO; ++ goto bailout; ++ } ++ } ++ } ++ ret = i; ++ ++bailout: ++ bit_dbg(3, &i2c_adap->dev, "emitting stop condition\n"); ++ i2c_stop(adap); ++ ++ if (adap->post_xfer) ++ adap->post_xfer(i2c_adap); ++ return ret; ++} ++ ++ ++const struct i2c_algorithm i2c_bit_algo = { ++ .master_xfer = bit_xfer, ++ .functionality = bit_func, ++}; ++EXPORT_SYMBOL_GPL(i2c_bit_algo); ++#endif ++ ++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); diff --cc compat/compat/compat-3.5.c index 000000000000,000000000000..d7f1c2751a86 new file mode 100644 --- /dev/null +++ b/compat/compat/compat-3.5.c @@@ -1,0 -1,0 +1,45 @@@ ++/* ++ * Copyright 2012-2013 Luis R. Rodriguez ++ * ++ * 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 ++#include ++#include ++ ++/* ++ * Commit 7a4e7408c5cadb240e068a662251754a562355e3 ++ * exported overflowuid and overflowgid for all ++ * kernel configurations, prior to that we only ++ * had it exported when CONFIG_UID16 was enabled. ++ * We are technically redefining it here but ++ * nothing seems to be changing it, except ++ * kernel/ code does epose it via sysctl and ++ * proc... if required later we can add that here. ++ */ ++#ifndef CONFIG_UID16 ++int overflowuid = DEFAULT_OVERFLOWUID; ++int overflowgid = DEFAULT_OVERFLOWGID; ++ ++EXPORT_SYMBOL_GPL(overflowuid); ++EXPORT_SYMBOL_GPL(overflowgid); ++#endif ++ ++/* ++ * We can't access the timekeeper static variable ++ * on older kernels so we're shit out of luck and ++ * have to rely on time that might jump. Upgrade ++ * if you want timestamps that don't jump, this ++ * important for DRM vblank and page flip event ++ * timestamps. ++ */ ++ktime_t ktime_get_monotonic_offset(void) ++{ ++ return ktime_get(); ++} ++EXPORT_SYMBOL_GPL(ktime_get_monotonic_offset); diff --cc compat/compat/compat-3.6.c index 000000000000,000000000000..113e3a867221 new file mode 100644 --- /dev/null +++ b/compat/compat/compat-3.6.c @@@ -1,0 -1,0 +1,76 @@@ ++/* ++ * Copyright (c) 2013 Luis R. Rodriguez ++ * ++ * Backport compatibility file for Linux for kernels 3.6. ++ * ++ * 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. ++ */ ++ ++#include ++#include ++ ++/** ++ * sg_alloc_table_from_pages - Allocate and initialize an sg table from ++ * an array of pages ++ * @sgt: The sg table header to use ++ * @pages: Pointer to an array of page pointers ++ * @n_pages: Number of pages in the pages array ++ * @offset: Offset from start of the first page to the start of a buffer ++ * @size: Number of valid bytes in the buffer (after offset) ++ * @gfp_mask: GFP allocation mask ++ * ++ * Description: ++ * Allocate and initialize an sg table from a list of pages. Contiguous ++ * ranges of the pages are squashed into a single scatterlist node. A user ++ * may provide an offset at a start and a size of valid data in a buffer ++ * specified by the page array. The returned sg table is released by ++ * sg_free_table. ++ * ++ * Returns: ++ * 0 on success, negative error on failure ++ */ ++int sg_alloc_table_from_pages(struct sg_table *sgt, ++ struct page **pages, unsigned int n_pages, ++ unsigned long offset, unsigned long size, ++ gfp_t gfp_mask) ++{ ++ unsigned int chunks; ++ unsigned int i; ++ unsigned int cur_page; ++ int ret; ++ struct scatterlist *s; ++ ++ /* compute number of contiguous chunks */ ++ chunks = 1; ++ for (i = 1; i < n_pages; ++i) ++ if (page_to_pfn(pages[i]) != page_to_pfn(pages[i - 1]) + 1) ++ ++chunks; ++ ++ ret = sg_alloc_table(sgt, chunks, gfp_mask); ++ if (unlikely(ret)) ++ return ret; ++ ++ /* merging chunks and putting them into the scatterlist */ ++ cur_page = 0; ++ for_each_sg(sgt->sgl, s, sgt->orig_nents, i) { ++ unsigned long chunk_size; ++ unsigned int j; ++ ++ /* look for the end of the current chunk */ ++ for (j = cur_page + 1; j < n_pages; ++j) ++ if (page_to_pfn(pages[j]) != ++ page_to_pfn(pages[j - 1]) + 1) ++ break; ++ ++ chunk_size = ((j - cur_page) << PAGE_SHIFT) - offset; ++ sg_set_page(s, pages[cur_page], min(size, chunk_size), offset); ++ size -= chunk_size; ++ offset = 0; ++ cur_page = j; ++ } ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(sg_alloc_table_from_pages); diff --cc compat/compat/compat-3.7.c index 000000000000,000000000000..226d136a3dba new file mode 100644 --- /dev/null +++ b/compat/compat/compat-3.7.c @@@ -1,0 -1,0 +1,251 @@@ ++/* ++ * Copyright 2012 Luis R. Rodriguez ++ * ++ * 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.7. ++ */ ++ ++#include ++#include ++ ++bool mod_delayed_work(struct workqueue_struct *wq, struct delayed_work *dwork, ++ unsigned long delay) ++{ ++ cancel_delayed_work(dwork); ++ queue_delayed_work(wq, dwork, delay); ++ return false; ++} ++EXPORT_SYMBOL_GPL(mod_delayed_work); ++ ++/* ++ * Kernels >= 3.7 get their PCI-E Capabilities Register cached ++ * via the pci_dev->pcie_flags_reg so for older kernels we have ++ * no other option but to read this every single time we need ++ * it accessed. If we really cared to improve the efficiency ++ * of this we could try to find an unused u16 varible on the ++ * pci_dev but if we found it we likely would remove it from ++ * the kernel anyway right? Bite me. ++ */ ++static inline u16 pcie_flags_reg(struct pci_dev *dev) ++{ ++ int pos; ++ u16 reg16; ++ ++ pos = pci_find_capability(dev, PCI_CAP_ID_EXP); ++ if (!pos) ++ return 0; ++ ++ pci_read_config_word(dev, pos + PCI_EXP_FLAGS, ®16); ++ ++ return reg16; ++} ++ ++static inline int pci_pcie_type(struct pci_dev *dev) ++{ ++ return (pcie_flags_reg(dev) & PCI_EXP_FLAGS_TYPE) >> 4; ++} ++ ++static inline int pcie_cap_version(struct pci_dev *dev) ++{ ++ return pcie_flags_reg(dev) & PCI_EXP_FLAGS_VERS; ++} ++ ++static inline bool pcie_cap_has_devctl(const struct pci_dev *dev) ++{ ++ return true; ++} ++ ++static inline bool pcie_cap_has_lnkctl(struct pci_dev *dev) ++{ ++ int type = pci_pcie_type(dev); ++ ++ return pcie_cap_version(dev) > 1 || ++ type == PCI_EXP_TYPE_ROOT_PORT || ++ type == PCI_EXP_TYPE_ENDPOINT || ++ type == PCI_EXP_TYPE_LEG_END; ++} ++ ++static inline bool pcie_cap_has_sltctl(struct pci_dev *dev) ++{ ++ int type = pci_pcie_type(dev); ++ ++ return pcie_cap_version(dev) > 1 || ++ type == PCI_EXP_TYPE_ROOT_PORT || ++ (type == PCI_EXP_TYPE_DOWNSTREAM && ++ pcie_flags_reg(dev) & PCI_EXP_FLAGS_SLOT); ++} ++ ++static inline bool pcie_cap_has_rtctl(struct pci_dev *dev) ++{ ++ int type = pci_pcie_type(dev); ++ ++ return pcie_cap_version(dev) > 1 || ++ type == PCI_EXP_TYPE_ROOT_PORT || ++ type == PCI_EXP_TYPE_RC_EC; ++} ++ ++static bool pcie_capability_reg_implemented(struct pci_dev *dev, int pos) ++{ ++ if (!pci_is_pcie(dev)) ++ return false; ++ ++ switch (pos) { ++ case PCI_EXP_FLAGS_TYPE: ++ return true; ++ case PCI_EXP_DEVCAP: ++ case PCI_EXP_DEVCTL: ++ case PCI_EXP_DEVSTA: ++ return pcie_cap_has_devctl(dev); ++ case PCI_EXP_LNKCAP: ++ case PCI_EXP_LNKCTL: ++ case PCI_EXP_LNKSTA: ++ return pcie_cap_has_lnkctl(dev); ++ case PCI_EXP_SLTCAP: ++ case PCI_EXP_SLTCTL: ++ case PCI_EXP_SLTSTA: ++ return pcie_cap_has_sltctl(dev); ++ case PCI_EXP_RTCTL: ++ case PCI_EXP_RTCAP: ++ case PCI_EXP_RTSTA: ++ return pcie_cap_has_rtctl(dev); ++ case PCI_EXP_DEVCAP2: ++ case PCI_EXP_DEVCTL2: ++ case PCI_EXP_LNKCAP2: ++ case PCI_EXP_LNKCTL2: ++ case PCI_EXP_LNKSTA2: ++ return pcie_cap_version(dev) > 1; ++ default: ++ return false; ++ } ++} ++ ++/* ++ * Note that these accessor functions are only for the "PCI Express ++ * Capability" (see PCIe spec r3.0, sec 7.8). They do not apply to the ++ * other "PCI Express Extended Capabilities" (AER, VC, ACS, MFVC, etc.) ++ */ ++int pcie_capability_read_word(struct pci_dev *dev, int pos, u16 *val) ++{ ++ int ret; ++ ++ *val = 0; ++ if (pos & 1) ++ return -EINVAL; ++ ++ if (pcie_capability_reg_implemented(dev, pos)) { ++ ret = pci_read_config_word(dev, pci_pcie_cap(dev) + pos, val); ++ /* ++ * Reset *val to 0 if pci_read_config_word() fails, it may ++ * have been written as 0xFFFF if hardware error happens ++ * during pci_read_config_word(). ++ */ ++ if (ret) ++ *val = 0; ++ return ret; ++ } ++ ++ /* ++ * For Functions that do not implement the Slot Capabilities, ++ * Slot Status, and Slot Control registers, these spaces must ++ * be hardwired to 0b, with the exception of the Presence Detect ++ * State bit in the Slot Status register of Downstream Ports, ++ * which must be hardwired to 1b. (PCIe Base Spec 3.0, sec 7.8) ++ */ ++ if (pci_is_pcie(dev) && pos == PCI_EXP_SLTSTA && ++ pci_pcie_type(dev) == PCI_EXP_TYPE_DOWNSTREAM) { ++ *val = PCI_EXP_SLTSTA_PDS; ++ } ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(pcie_capability_read_word); ++ ++int pcie_capability_read_dword(struct pci_dev *dev, int pos, u32 *val) ++{ ++ int ret; ++ ++ *val = 0; ++ if (pos & 3) ++ return -EINVAL; ++ ++ if (pcie_capability_reg_implemented(dev, pos)) { ++ ret = pci_read_config_dword(dev, pci_pcie_cap(dev) + pos, val); ++ /* ++ * Reset *val to 0 if pci_read_config_dword() fails, it may ++ * have been written as 0xFFFFFFFF if hardware error happens ++ * during pci_read_config_dword(). ++ */ ++ if (ret) ++ *val = 0; ++ return ret; ++ } ++ ++ if (pci_is_pcie(dev) && pos == PCI_EXP_SLTCTL && ++ pci_pcie_type(dev) == PCI_EXP_TYPE_DOWNSTREAM) { ++ *val = PCI_EXP_SLTSTA_PDS; ++ } ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(pcie_capability_read_dword); ++ ++int pcie_capability_write_word(struct pci_dev *dev, int pos, u16 val) ++{ ++ if (pos & 1) ++ return -EINVAL; ++ ++ if (!pcie_capability_reg_implemented(dev, pos)) ++ return 0; ++ ++ return pci_write_config_word(dev, pci_pcie_cap(dev) + pos, val); ++} ++EXPORT_SYMBOL_GPL(pcie_capability_write_word); ++ ++int pcie_capability_write_dword(struct pci_dev *dev, int pos, u32 val) ++{ ++ if (pos & 3) ++ return -EINVAL; ++ ++ if (!pcie_capability_reg_implemented(dev, pos)) ++ return 0; ++ ++ return pci_write_config_dword(dev, pci_pcie_cap(dev) + pos, val); ++} ++EXPORT_SYMBOL_GPL(pcie_capability_write_dword); ++ ++int pcie_capability_clear_and_set_word(struct pci_dev *dev, int pos, ++ u16 clear, u16 set) ++{ ++ int ret; ++ u16 val; ++ ++ ret = pcie_capability_read_word(dev, pos, &val); ++ if (!ret) { ++ val &= ~clear; ++ val |= set; ++ ret = pcie_capability_write_word(dev, pos, val); ++ } ++ ++ return ret; ++} ++EXPORT_SYMBOL_GPL(pcie_capability_clear_and_set_word); ++ ++int pcie_capability_clear_and_set_dword(struct pci_dev *dev, int pos, ++ u32 clear, u32 set) ++{ ++ int ret; ++ u32 val; ++ ++ ret = pcie_capability_read_dword(dev, pos, &val); ++ if (!ret) { ++ val &= ~clear; ++ val |= set; ++ ret = pcie_capability_write_dword(dev, pos, val); ++ } ++ ++ return ret; ++} ++EXPORT_SYMBOL_GPL(pcie_capability_clear_and_set_dword); diff --cc compat/compat/compat-3.8.c index 000000000000,000000000000..8134323453ac new file mode 100644 --- /dev/null +++ b/compat/compat/compat-3.8.c @@@ -1,0 -1,0 +1,365 @@@ ++/* ++ * Copyright (c) 1999 Andreas Gal ++ * Copyright (c) 2000-2005 Vojtech Pavlik ++ * Copyright (c) 2005 Michael Haboustak for Concept2, Inc ++ * Copyright (c) 2006-2012 Jiri Kosina ++ * Copyright (c) 2012 Luis R. Rodriguez ++ * ++ * Compatibility file for Linux wireless for kernels 3.8. ++ * ++ * 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. ++ */ ++ ++#include ++#include ++#include ++#include "hid-ids.h" ++#include ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,7,8)) ++void netdev_set_default_ethtool_ops(struct net_device *dev, ++ const struct ethtool_ops *ops) ++{ ++ if (!dev->ethtool_ops) ++ dev->ethtool_ops = ops; ++} ++EXPORT_SYMBOL_GPL(netdev_set_default_ethtool_ops); ++#endif ++ ++/* a list of devices that shouldn't be handled by HID core at all */ ++static const struct hid_device_id hid_ignore_list[] = { ++ { HID_USB_DEVICE(USB_VENDOR_ID_ACECAD, USB_DEVICE_ID_ACECAD_FLAIR) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_ACECAD, USB_DEVICE_ID_ACECAD_302) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_ADS_TECH, USB_DEVICE_ID_ADS_TECH_RADIO_SI470X) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_01) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_10) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_20) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_21) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_22) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_23) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_24) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_AIRCABLE, USB_DEVICE_ID_AIRCABLE1) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_ALCOR, USB_DEVICE_ID_ALCOR_USBRS232) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_LCM)}, ++ { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_LCM2)}, ++ { HID_USB_DEVICE(USB_VENDOR_ID_AVERMEDIA, USB_DEVICE_ID_AVER_FM_MR800) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_AXENTIA, USB_DEVICE_ID_AXENTIA_FM_RADIO) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_BERKSHIRE, USB_DEVICE_ID_BERKSHIRE_PCWD) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_CIDC, 0x0103) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_CYGNAL, USB_DEVICE_ID_CYGNAL_RADIO_SI470X) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_CMEDIA, USB_DEVICE_ID_CM109) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_HIDCOM) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_ULTRAMOUSE) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_DEALEXTREAME, USB_DEVICE_ID_DEALEXTREAME_RADIO_SI4701) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EARTHMATE) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EM_LT20) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_DREAM_CHEEKY, 0x0004) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_DREAM_CHEEKY, 0x000a) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_ESSENTIAL_REALITY, USB_DEVICE_ID_ESSENTIAL_REALITY_P5) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_ETT, USB_DEVICE_ID_TC5UH) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_ETT, USB_DEVICE_ID_TC4UM) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 0x0001) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 0x0002) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 0x0004) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_4_PHIDGETSERVO_30) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_1_PHIDGETSERVO_30) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_0_0_4_IF_KIT) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_0_16_16_IF_KIT) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_8_8_8_IF_KIT) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_0_8_7_IF_KIT) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_0_8_8_IF_KIT) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_PHIDGET_MOTORCONTROL) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_GOTOP, USB_DEVICE_ID_SUPER_Q2) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_GOTOP, USB_DEVICE_ID_GOGOPEN) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_GOTOP, USB_DEVICE_ID_PENPOWER) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_GRETAGMACBETH, USB_DEVICE_ID_GRETAGMACBETH_HUEY) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_POWERMATE) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_SOUNDKNOB) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_RADIOSHARK) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_90) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_100) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_101) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_103) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_104) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_105) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_106) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_107) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_108) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_200) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_201) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_202) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_203) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_204) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_205) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_206) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_207) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_300) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_301) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_302) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_303) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_304) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_305) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_306) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_307) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_308) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_309) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_400) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_401) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_402) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_403) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_404) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_405) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_500) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_501) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_502) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_503) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_504) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1000) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1001) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1002) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1003) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1004) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1005) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1006) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1007) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_IMATION, USB_DEVICE_ID_DISC_STAKKA) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_KBGEAR, USB_DEVICE_ID_KBGEAR_JAMSTUDIO) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_KWORLD, USB_DEVICE_ID_KWORLD_RADIO_FM700) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_GPEN_560) }, ++ { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_KYE, 0x0058) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_CASSY) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_CASSY2) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_POCKETCASSY) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_POCKETCASSY2) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MOBILECASSY) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MOBILECASSY2) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MICROCASSYVOLTAGE) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MICROCASSYCURRENT) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MICROCASSYTIME) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MICROCASSYTEMPERATURE) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MICROCASSYPH) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_JWM) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_DMMP) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_UMIP) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_UMIC) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_UMIB) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_XRAY) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_XRAY2) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_VIDEOCOM) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MOTOR) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_COM3LAB) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_TELEPORT) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_NETWORKANALYSER) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_POWERCONTROL) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MACHINETEST) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MOSTANALYSER) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MOSTANALYSER2) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_ABSESP) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_AUTODATABUS) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MCT) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_HYBRID) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_HEATCONTROL) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_MADCATZ, USB_DEVICE_ID_MADCATZ_BEATPAD) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_MCC, USB_DEVICE_ID_MCC_PMD1024LS) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_MCC, USB_DEVICE_ID_MCC_PMD1208LS) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICKIT1) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICKIT2) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_NATIONAL_SEMICONDUCTOR, USB_DEVICE_ID_N_S_HARMONY) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 20) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 30) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 100) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 108) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 118) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 200) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 300) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 400) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 500) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_PANJIT, 0x0001) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_PANJIT, 0x0002) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_PANJIT, 0x0003) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_PANJIT, 0x0004) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_PHILIPS, USB_DEVICE_ID_PHILIPS_IEEE802154_DONGLE) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_POWERCOM, USB_DEVICE_ID_POWERCOM_UPS) }, ++#if defined(CONFIG_MOUSE_SYNAPTICS_USB) || defined(CONFIG_MOUSE_SYNAPTICS_USB_MODULE) ++ { HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_TP) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_INT_TP) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_CPAD) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_STICK) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_WP) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_COMP_TP) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_WTP) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_DPAD) }, ++#endif ++ { HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_LABPRO) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_GOTEMP) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_SKIP) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_CYCLOPS) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_LCSPEC) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_WACOM, HID_ANY_ID) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_4_PHIDGETSERVO_20) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_1_PHIDGETSERVO_20) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_8_8_4_IF_KIT) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_YEALINK, USB_DEVICE_ID_YEALINK_P1K_P4K_B2K) }, ++ { } ++}; ++ ++/** ++ * hid_mouse_ignore_list - mouse devices which should not be handled by the hid layer ++ * ++ * There are composite devices for which we want to ignore only a certain ++ * interface. This is a list of devices for which only the mouse interface will ++ * be ignored. This allows a dedicated driver to take care of the interface. ++ */ ++static const struct hid_device_id hid_mouse_ignore_list[] = { ++ /* appletouch driver */ ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ISO) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ANSI) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ISO) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_JIS) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ANSI) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ISO) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_JIS) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ANSI) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ISO) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_JIS) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ANSI) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ISO) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_JIS) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ANSI) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ISO) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_JIS) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ISO) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_JIS) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_ISO) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_JIS) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4_ISO) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4_JIS) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4A_ANSI) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4A_ISO) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5_ANSI) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5_ISO) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5_JIS) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5A_ANSI) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5A_ISO) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5A_JIS) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6_ANSI) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6_ISO) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6_JIS) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6A_ANSI) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6A_ISO) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6A_JIS) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7_ANSI) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7_ISO) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7_JIS) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7A_ANSI) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7A_ISO) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7A_JIS) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) }, ++ { } ++}; ++ ++static bool hid_match_one_id(struct hid_device *hdev, ++ const struct hid_device_id *id) ++{ ++ return (id->bus == HID_BUS_ANY || id->bus == hdev->bus) && ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)) ++ (id->group == HID_GROUP_ANY || id->group == hdev->group) && ++#endif ++ (id->vendor == HID_ANY_ID || id->vendor == hdev->vendor) && ++ (id->product == HID_ANY_ID || id->product == hdev->product); ++} ++ ++const struct hid_device_id *hid_match_id(struct hid_device *hdev, ++ const struct hid_device_id *id) ++{ ++ for (; id->bus; id++) ++ if (hid_match_one_id(hdev, id)) ++ return id; ++ ++ return NULL; ++} ++ ++bool hid_ignore(struct hid_device *hdev) ++{ ++ if (hdev->quirks & HID_QUIRK_NO_IGNORE) ++ return false; ++ if (hdev->quirks & HID_QUIRK_IGNORE) ++ return true; ++ ++ switch (hdev->vendor) { ++ case USB_VENDOR_ID_CODEMERCS: ++ /* ignore all Code Mercenaries IOWarrior devices */ ++ if (hdev->product >= USB_DEVICE_ID_CODEMERCS_IOW_FIRST && ++ hdev->product <= USB_DEVICE_ID_CODEMERCS_IOW_LAST) ++ return true; ++ break; ++ case USB_VENDOR_ID_LOGITECH: ++ if (hdev->product >= USB_DEVICE_ID_LOGITECH_HARMONY_FIRST && ++ hdev->product <= USB_DEVICE_ID_LOGITECH_HARMONY_LAST) ++ return true; ++ /* ++ * The Keene FM transmitter USB device has the same USB ID as ++ * the Logitech AudioHub Speaker, but it should ignore the hid. ++ * Check if the name is that of the Keene device. ++ * For reference: the name of the AudioHub is ++ * "HOLTEK AudioHub Speaker". ++ */ ++ if (hdev->product == USB_DEVICE_ID_LOGITECH_AUDIOHUB && ++ !strcmp(hdev->name, "HOLTEK B-LINK USB Audio ")) ++ return true; ++ break; ++ case USB_VENDOR_ID_SOUNDGRAPH: ++ if (hdev->product >= USB_DEVICE_ID_SOUNDGRAPH_IMON_FIRST && ++ hdev->product <= USB_DEVICE_ID_SOUNDGRAPH_IMON_LAST) ++ return true; ++ break; ++ case USB_VENDOR_ID_HANWANG: ++ if (hdev->product >= USB_DEVICE_ID_HANWANG_TABLET_FIRST && ++ hdev->product <= USB_DEVICE_ID_HANWANG_TABLET_LAST) ++ return true; ++ break; ++ case USB_VENDOR_ID_JESS: ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28)) ++ if (hdev->product == USB_DEVICE_ID_JESS_YUREX && ++ hdev->type == HID_TYPE_USBNONE) ++ return true; ++#else ++ if (hdev->product == USB_DEVICE_ID_JESS_YUREX) ++ return true; ++#endif ++ break; ++ case USB_VENDOR_ID_DWAV: ++ /* These are handled by usbtouchscreen. hdev->type is probably ++ * HID_TYPE_USBNONE, but we say !HID_TYPE_USBMOUSE to match ++ * usbtouchscreen. */ ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28)) ++ if ((hdev->product == USB_DEVICE_ID_EGALAX_TOUCHCONTROLLER || ++ hdev->product == USB_DEVICE_ID_DWAV_TOUCHCONTROLLER) && ++ hdev->type != HID_TYPE_USBMOUSE) ++ return true; ++#else ++ if (hdev->product == USB_DEVICE_ID_EGALAX_TOUCHCONTROLLER || ++ hdev->product == USB_DEVICE_ID_DWAV_TOUCHCONTROLLER) ++ return true; ++#endif ++ break; ++ } ++ ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28)) ++ if (hdev->type == HID_TYPE_USBMOUSE && ++ hid_match_id(hdev, hid_mouse_ignore_list)) ++ return true; ++#endif ++ ++ return !!hid_match_id(hdev, hid_ignore_list); ++} ++EXPORT_SYMBOL_GPL(hid_ignore); diff --cc compat/compat/compat-3.9.c index 000000000000,000000000000..1f2484216f92 new file mode 100644 --- /dev/null +++ b/compat/compat/compat-3.9.c @@@ -1,0 -1,0 +1,54 @@@ ++/* ++ * Copyright (c) 2013 Luis R. Rodriguez ++ * ++ * Compatibility file for Linux wireless for kernels 3.9. ++ * ++ * 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. ++ */ ++ ++#include ++#include ++ ++#ifdef __sg_page_iter_next ++ ++void __sg_page_iter_start(struct sg_page_iter *piter, ++ struct scatterlist *sglist, unsigned int nents, ++ unsigned long pgoffset) ++{ ++ piter->__pg_advance = 0; ++ piter->__nents = nents; ++ ++ piter->page = NULL; ++ piter->sg = sglist; ++ piter->sg_pgoffset = pgoffset; ++} ++EXPORT_SYMBOL_GPL(__sg_page_iter_start); ++ ++static int sg_page_count(struct scatterlist *sg) ++{ ++ return PAGE_ALIGN(sg->offset + sg->length) >> PAGE_SHIFT; ++} ++ ++bool __sg_page_iter_next(struct sg_page_iter *piter) ++{ ++ if (!piter->__nents || !piter->sg) ++ return false; ++ ++ piter->sg_pgoffset += piter->__pg_advance; ++ piter->__pg_advance = 1; ++ ++ while (piter->sg_pgoffset >= sg_page_count(piter->sg)) { ++ piter->sg_pgoffset -= sg_page_count(piter->sg); ++ piter->sg = sg_next(piter->sg); ++ if (!--piter->__nents || !piter->sg) ++ return false; ++ } ++ piter->page = nth_page(sg_page(piter->sg), piter->sg_pgoffset); ++ ++ return true; ++} ++EXPORT_SYMBOL_GPL(__sg_page_iter_next); ++ ++#endif /* __sg_page_iter_next */ diff --cc compat/compat/compat_atomic.c index 000000000000,000000000000..b8565aa5b2bc new file mode 100644 --- /dev/null +++ b/compat/compat/compat_atomic.c @@@ -1,0 -1,0 +1,33 @@@ ++#include ++#include ++ ++#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 ++ diff --cc compat/compat/compat_firmware_class.c index 000000000000,000000000000..9ea5080e3f93 new file mode 100644 --- /dev/null +++ b/compat/compat/compat_firmware_class.c @@@ -1,0 -1,0 +1,759 @@@ ++/* ++ * firmware_class.c - Multi purpose firmware loading support ++ * ++ * Copyright (c) 2003 Manuel Estrada Sainz ++ * ++ * Please see Documentation/firmware_class/ for more information. ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define backport_firmware_to_dev(obj) container_of(obj, struct device, kobj) ++ ++MODULE_AUTHOR("Manuel Estrada Sainz"); ++MODULE_DESCRIPTION("Multi purpose firmware loading support"); ++MODULE_LICENSE("GPL"); ++ ++/* Builtin firmware support */ ++ ++//#ifdef CONFIG_FW_LOADER ++#if 0 ++ ++extern struct builtin_fw __start_builtin_fw[]; ++extern struct builtin_fw __end_builtin_fw[]; ++ ++static bool fw_get_builtin_firmware(struct firmware *fw, const char *name) ++{ ++ struct builtin_fw *b_fw; ++ ++ for (b_fw = __start_builtin_fw; b_fw != __end_builtin_fw; b_fw++) { ++ if (strcmp(name, b_fw->name) == 0) { ++ fw->size = b_fw->size; ++ fw->data = b_fw->data; ++ return true; ++ } ++ } ++ ++ return false; ++} ++ ++static bool fw_is_builtin_firmware(const struct firmware *fw) ++{ ++ struct builtin_fw *b_fw; ++ ++ for (b_fw = __start_builtin_fw; b_fw != __end_builtin_fw; b_fw++) ++ if (fw->data == b_fw->data) ++ return true; ++ ++ return false; ++} ++ ++#else /* Module case - no builtin firmware support */ ++ ++static inline bool fw_get_builtin_firmware(struct firmware *fw, const char *name) ++{ ++ return false; ++} ++ ++static inline bool fw_is_builtin_firmware(const struct firmware *fw) ++{ ++ return false; ++} ++#endif ++ ++enum { ++ FW_STATUS_LOADING, ++ FW_STATUS_DONE, ++ FW_STATUS_ABORT, ++}; ++ ++static int loading_timeout = 60; /* In seconds */ ++ ++/* fw_lock could be moved to 'struct firmware_priv' but since it is just ++ * guarding for corner cases a global lock should be OK */ ++static DEFINE_MUTEX(fw_lock); ++ ++struct firmware_priv { ++ struct completion completion; ++ struct firmware *fw; ++ unsigned long status; ++ struct page **pages; ++ int nr_pages; ++ int page_array_size; ++ struct timer_list timeout; ++ struct device dev; ++ bool nowait; ++ char fw_id[]; ++}; ++ ++static struct firmware_priv *to_firmware_priv(struct device *dev) ++{ ++ return container_of(dev, struct firmware_priv, dev); ++} ++ ++static void fw_load_abort(struct firmware_priv *fw_priv) ++{ ++ set_bit(FW_STATUS_ABORT, &fw_priv->status); ++ wmb(); ++ complete(&fw_priv->completion); ++} ++ ++static ssize_t firmware_timeout_show(struct class *class, ++ char *buf) ++{ ++ return sprintf(buf, "%d\n", loading_timeout); ++} ++ ++/** ++ * firmware_timeout_store - set number of seconds to wait for firmware ++ * @class: device class pointer ++ * @buf: buffer to scan for timeout value ++ * @count: number of bytes in @buf ++ * ++ * Sets the number of seconds to wait for the firmware. Once ++ * this expires an error will be returned to the driver and no ++ * firmware will be provided. ++ * ++ * Note: zero means 'wait forever'. ++ **/ ++static ssize_t firmware_timeout_store(struct class *class, ++ const char *buf, size_t count) ++{ ++ loading_timeout = simple_strtol(buf, NULL, 10); ++ if (loading_timeout < 0) ++ loading_timeout = 0; ++ ++ return count; ++} ++ ++static struct class_attribute firmware_class_attrs[] = { ++ __ATTR(timeout, S_IWUSR | S_IRUGO, ++ firmware_timeout_show, firmware_timeout_store), ++ __ATTR_NULL ++}; ++ ++static void fw_dev_release(struct device *dev) ++{ ++ struct firmware_priv *fw_priv = to_firmware_priv(dev); ++ int i; ++ ++ for (i = 0; i < fw_priv->nr_pages; i++) ++ __free_page(fw_priv->pages[i]); ++ kfree(fw_priv->pages); ++ kfree(fw_priv); ++ ++ module_put(THIS_MODULE); ++} ++ ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)) ++static int firmware_uevent(struct device *dev, struct kobj_uevent_env *env) ++{ ++ struct firmware_priv *fw_priv = to_firmware_priv(dev); ++ ++ if (add_uevent_var(env, "FIRMWARE=%s", fw_priv->fw_id)) ++ return -ENOMEM; ++ if (add_uevent_var(env, "TIMEOUT=%i", loading_timeout)) ++ return -ENOMEM; ++ if (add_uevent_var(env, "ASYNC=%d", fw_priv->nowait)) ++ return -ENOMEM; ++ ++ return 0; ++} ++#else ++static int firmware_uevent(struct device *dev, char **envp, ++ int num_envp, char *buf, int size) ++{ ++ struct firmware_priv *fw_priv = to_firmware_priv(dev); ++ int error, len = 0, i = 0; ++ ++ error = add_uevent_var(envp, num_envp, &i, ++ buf, size, &len, ++ "FIRMWARE=%s", fw_priv->fw_id); ++ if (error) ++ goto exit; ++ ++ error = add_uevent_var(envp, num_envp, &i, ++ buf, size, &len, ++ "TIMEOUT=%i", loading_timeout); ++ if (error) ++ goto exit; ++ error = add_uevent_var(envp, num_envp, &i, ++ buf, size, &len, ++ "ASYNC=%i", fw_priv->nowait); ++ if (error) ++ goto exit; ++ ++ return 0; ++exit: ++ envp[i] = NULL; ++ return error; ++} ++#endif ++ ++static struct class firmware_class = { ++ .name = "compat_firmware", ++ .class_attrs = firmware_class_attrs, ++ .dev_uevent = firmware_uevent, ++ .dev_release = fw_dev_release, ++}; ++ ++static ssize_t firmware_loading_show(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ struct firmware_priv *fw_priv = to_firmware_priv(dev); ++ int loading = test_bit(FW_STATUS_LOADING, &fw_priv->status); ++ ++ return sprintf(buf, "%d\n", loading); ++} ++ ++static void firmware_free_data(const struct firmware *fw) ++{ ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35)) ++ int i; ++ vunmap(fw->data); ++ if (fw->pages) { ++ for (i = 0; i < PFN_UP(fw->size); i++) ++ __free_page(fw->pages[i]); ++ kfree(fw->pages); ++ } ++#else ++ vunmap(fw->data); ++#endif ++} ++ ++/* Some architectures don't have PAGE_KERNEL_RO */ ++#ifndef PAGE_KERNEL_RO ++#define PAGE_KERNEL_RO PAGE_KERNEL ++#endif ++/** ++ * firmware_loading_store - set value in the 'loading' control file ++ * @dev: device pointer ++ * @buf: buffer to scan for loading control value ++ * @count: number of bytes in @buf ++ * ++ * The relevant values are: ++ * ++ * 1: Start a load, discarding any previous partial load. ++ * 0: Conclude the load and hand the data to the driver code. ++ * -1: Conclude the load with an error and discard any written data. ++ **/ ++static ssize_t firmware_loading_store(struct device *dev, ++ struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ struct firmware_priv *fw_priv = to_firmware_priv(dev); ++ int loading = simple_strtol(buf, NULL, 10); ++ int i; ++ ++ switch (loading) { ++ case 1: ++ mutex_lock(&fw_lock); ++ if (!fw_priv->fw) { ++ mutex_unlock(&fw_lock); ++ break; ++ } ++ firmware_free_data(fw_priv->fw); ++ memset(fw_priv->fw, 0, sizeof(struct firmware)); ++ /* If the pages are not owned by 'struct firmware' */ ++ for (i = 0; i < fw_priv->nr_pages; i++) ++ __free_page(fw_priv->pages[i]); ++ kfree(fw_priv->pages); ++ fw_priv->pages = NULL; ++ fw_priv->page_array_size = 0; ++ fw_priv->nr_pages = 0; ++ set_bit(FW_STATUS_LOADING, &fw_priv->status); ++ mutex_unlock(&fw_lock); ++ break; ++ case 0: ++ if (test_bit(FW_STATUS_LOADING, &fw_priv->status)) { ++ vunmap(fw_priv->fw->data); ++ fw_priv->fw->data = vmap(fw_priv->pages, ++ fw_priv->nr_pages, ++ 0, PAGE_KERNEL_RO); ++ if (!fw_priv->fw->data) { ++ dev_err(dev, "%s: vmap() failed\n", __func__); ++ goto err; ++ } ++ /* Pages are now owned by 'struct firmware' */ ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35)) ++ fw_priv->fw->pages = fw_priv->pages; ++ fw_priv->pages = NULL; ++#endif ++ ++ fw_priv->page_array_size = 0; ++ fw_priv->nr_pages = 0; ++ complete(&fw_priv->completion); ++ clear_bit(FW_STATUS_LOADING, &fw_priv->status); ++ break; ++ } ++ /* fallthrough */ ++ default: ++ dev_err(dev, "%s: unexpected value (%d)\n", __func__, loading); ++ /* fallthrough */ ++ case -1: ++ err: ++ fw_load_abort(fw_priv); ++ break; ++ } ++ ++ return count; ++} ++ ++static DEVICE_ATTR(loading, 0644, firmware_loading_show, firmware_loading_store); ++ ++#if defined(CONFIG_COMPAT_FIRMWARE_DATA_RW_NEEDS_FILP) ++static ssize_t firmware_data_read(struct file *filp, struct kobject *kobj, ++ struct bin_attribute *bin_attr, ++ char *buffer, loff_t offset, size_t count) ++#else ++static ssize_t firmware_data_read(struct kobject *kobj, ++ struct bin_attribute *bin_attr, ++ char *buffer, loff_t offset, size_t count) ++#endif ++{ ++ struct device *dev = backport_firmware_to_dev(kobj); ++ struct firmware_priv *fw_priv = to_firmware_priv(dev); ++ struct firmware *fw; ++ ssize_t ret_count; ++ ++ mutex_lock(&fw_lock); ++ fw = fw_priv->fw; ++ if (!fw || test_bit(FW_STATUS_DONE, &fw_priv->status)) { ++ ret_count = -ENODEV; ++ goto out; ++ } ++ if (offset > fw->size) { ++ ret_count = 0; ++ goto out; ++ } ++ if (count > fw->size - offset) ++ count = fw->size - offset; ++ ++ ret_count = count; ++ ++ while (count) { ++ void *page_data; ++ int page_nr = offset >> PAGE_SHIFT; ++ int page_ofs = offset & (PAGE_SIZE-1); ++ int page_cnt = min_t(size_t, PAGE_SIZE - page_ofs, count); ++ ++ page_data = kmap(fw_priv->pages[page_nr]); ++ ++ memcpy(buffer, page_data + page_ofs, page_cnt); ++ ++ kunmap(fw_priv->pages[page_nr]); ++ buffer += page_cnt; ++ offset += page_cnt; ++ count -= page_cnt; ++ } ++out: ++ mutex_unlock(&fw_lock); ++ return ret_count; ++} ++ ++static int fw_realloc_buffer(struct firmware_priv *fw_priv, int min_size) ++{ ++ int pages_needed = ALIGN(min_size, PAGE_SIZE) >> PAGE_SHIFT; ++ ++ /* If the array of pages is too small, grow it... */ ++ if (fw_priv->page_array_size < pages_needed) { ++ int new_array_size = max(pages_needed, ++ fw_priv->page_array_size * 2); ++ struct page **new_pages; ++ ++ new_pages = kmalloc(new_array_size * sizeof(void *), ++ GFP_KERNEL); ++ if (!new_pages) { ++ fw_load_abort(fw_priv); ++ return -ENOMEM; ++ } ++ memcpy(new_pages, fw_priv->pages, ++ fw_priv->page_array_size * sizeof(void *)); ++ memset(&new_pages[fw_priv->page_array_size], 0, sizeof(void *) * ++ (new_array_size - fw_priv->page_array_size)); ++ kfree(fw_priv->pages); ++ fw_priv->pages = new_pages; ++ fw_priv->page_array_size = new_array_size; ++ } ++ ++ while (fw_priv->nr_pages < pages_needed) { ++ fw_priv->pages[fw_priv->nr_pages] = ++ alloc_page(GFP_KERNEL | __GFP_HIGHMEM); ++ ++ if (!fw_priv->pages[fw_priv->nr_pages]) { ++ fw_load_abort(fw_priv); ++ return -ENOMEM; ++ } ++ fw_priv->nr_pages++; ++ } ++ return 0; ++} ++ ++/** ++ * firmware_data_write - write method for firmware ++ * @kobj: kobject for the device ++ * @bin_attr: bin_attr structure ++ * @buffer: buffer being written ++ * @offset: buffer offset for write in total data store area ++ * @count: buffer size ++ * ++ * Data written to the 'data' attribute will be later handed to ++ * the driver as a firmware image. ++ **/ ++#if defined(CONFIG_COMPAT_FIRMWARE_DATA_RW_NEEDS_FILP) ++static ssize_t firmware_data_write(struct file *filp, struct kobject *kobj, ++ struct bin_attribute *bin_attr, ++ char *buffer, loff_t offset, size_t count) ++#else ++static ssize_t firmware_data_write(struct kobject *kobj, ++ struct bin_attribute *bin_attr, ++ char *buffer, loff_t offset, size_t count) ++#endif ++{ ++ struct device *dev = backport_firmware_to_dev(kobj); ++ struct firmware_priv *fw_priv = to_firmware_priv(dev); ++ struct firmware *fw; ++ ssize_t retval; ++ ++ if (!capable(CAP_SYS_RAWIO)) ++ return -EPERM; ++ ++ mutex_lock(&fw_lock); ++ fw = fw_priv->fw; ++ if (!fw || test_bit(FW_STATUS_DONE, &fw_priv->status)) { ++ retval = -ENODEV; ++ goto out; ++ } ++ retval = fw_realloc_buffer(fw_priv, offset + count); ++ if (retval) ++ goto out; ++ ++ retval = count; ++ ++ while (count) { ++ void *page_data; ++ int page_nr = offset >> PAGE_SHIFT; ++ int page_ofs = offset & (PAGE_SIZE - 1); ++ int page_cnt = min_t(size_t, PAGE_SIZE - page_ofs, count); ++ ++ page_data = kmap(fw_priv->pages[page_nr]); ++ ++ memcpy(page_data + page_ofs, buffer, page_cnt); ++ ++ kunmap(fw_priv->pages[page_nr]); ++ buffer += page_cnt; ++ offset += page_cnt; ++ count -= page_cnt; ++ } ++ ++ fw->size = max_t(size_t, offset, fw->size); ++out: ++ mutex_unlock(&fw_lock); ++ return retval; ++} ++ ++static struct bin_attribute firmware_attr_data = { ++ .attr = { .name = "data", .mode = 0644 }, ++ .size = 0, ++ .read = firmware_data_read, ++ .write = firmware_data_write, ++}; ++ ++static void firmware_class_timeout(u_long data) ++{ ++ struct firmware_priv *fw_priv = (struct firmware_priv *) data; ++ ++ fw_load_abort(fw_priv); ++} ++ ++static struct firmware_priv * ++fw_create_instance(struct firmware *firmware, const char *fw_name, ++ struct device *device, bool uevent, bool nowait) ++{ ++ struct firmware_priv *fw_priv; ++ struct device *f_dev; ++ int error; ++ ++ fw_priv = kzalloc(sizeof(*fw_priv) + strlen(fw_name) + 1 , GFP_KERNEL); ++ if (!fw_priv) { ++ dev_err(device, "%s: kmalloc failed\n", __func__); ++ error = -ENOMEM; ++ goto err_out; ++ } ++ ++ fw_priv->fw = firmware; ++ fw_priv->nowait = nowait; ++ strcpy(fw_priv->fw_id, fw_name); ++ init_completion(&fw_priv->completion); ++ setup_timer(&fw_priv->timeout, ++ firmware_class_timeout, (u_long) fw_priv); ++ ++ f_dev = &fw_priv->dev; ++ ++ device_initialize(f_dev); ++ dev_set_name(f_dev, "%s", dev_name(device)); ++ f_dev->parent = device; ++ f_dev->class = &firmware_class; ++ ++ dev_set_uevent_suppress(f_dev, true); ++ ++ /* Need to pin this module until class device is destroyed */ ++ __module_get(THIS_MODULE); ++ ++ error = device_add(f_dev); ++ if (error) { ++ dev_err(device, "%s: device_register failed\n", __func__); ++ goto err_put_dev; ++ } ++ ++ error = device_create_bin_file(f_dev, &firmware_attr_data); ++ if (error) { ++ dev_err(device, "%s: sysfs_create_bin_file failed\n", __func__); ++ goto err_del_dev; ++ } ++ ++ error = device_create_file(f_dev, &dev_attr_loading); ++ if (error) { ++ dev_err(device, "%s: device_create_file failed\n", __func__); ++ goto err_del_bin_attr; ++ } ++ ++ if (uevent) ++ dev_set_uevent_suppress(f_dev, false); ++ ++ return fw_priv; ++ ++err_del_bin_attr: ++ device_remove_bin_file(f_dev, &firmware_attr_data); ++err_del_dev: ++ device_del(f_dev); ++err_put_dev: ++ put_device(f_dev); ++err_out: ++ return ERR_PTR(error); ++} ++ ++static void fw_destroy_instance(struct firmware_priv *fw_priv) ++{ ++ struct device *f_dev = &fw_priv->dev; ++ ++ device_remove_file(f_dev, &dev_attr_loading); ++ device_remove_bin_file(f_dev, &firmware_attr_data); ++ device_unregister(f_dev); ++} ++ ++static int _request_firmware(const struct firmware **firmware_p, ++ const char *name, struct device *device, ++ bool uevent, bool nowait) ++{ ++ struct firmware_priv *fw_priv; ++ struct firmware *firmware; ++ int retval = 0; ++ ++ if (!firmware_p) ++ return -EINVAL; ++ ++ *firmware_p = firmware = kzalloc(sizeof(*firmware), GFP_KERNEL); ++ if (!firmware) { ++ dev_err(device, "%s: kmalloc(struct firmware) failed\n", ++ __func__); ++ retval = -ENOMEM; ++ goto out; ++ } ++ ++ if (fw_get_builtin_firmware(firmware, name)) { ++ dev_dbg(device, "firmware: using built-in firmware %s\n", name); ++ return 0; ++ } ++ ++ if (uevent) ++ dev_dbg(device, "firmware: requesting %s\n", name); ++ ++ fw_priv = fw_create_instance(firmware, name, device, uevent, nowait); ++ if (IS_ERR(fw_priv)) { ++ retval = PTR_ERR(fw_priv); ++ goto out; ++ } ++ ++ if (uevent) { ++ if (loading_timeout > 0) ++ mod_timer(&fw_priv->timeout, ++ round_jiffies_up(jiffies + ++ loading_timeout * HZ)); ++ ++ kobject_uevent(&fw_priv->dev.kobj, KOBJ_ADD); ++ } ++ ++ wait_for_completion(&fw_priv->completion); ++ ++ set_bit(FW_STATUS_DONE, &fw_priv->status); ++ del_timer_sync(&fw_priv->timeout); ++ ++ mutex_lock(&fw_lock); ++ if (!fw_priv->fw->size || test_bit(FW_STATUS_ABORT, &fw_priv->status)) ++ retval = -ENOENT; ++ fw_priv->fw = NULL; ++ mutex_unlock(&fw_lock); ++ ++ fw_destroy_instance(fw_priv); ++ ++out: ++ if (retval) { ++ release_firmware(firmware); ++ *firmware_p = NULL; ++ } ++ ++ return retval; ++} ++ ++/** ++ * request_firmware: - send firmware request and wait for it ++ * @firmware_p: pointer to firmware image ++ * @name: name of firmware file ++ * @device: device for which firmware is being loaded ++ * ++ * @firmware_p will be used to return a firmware image by the name ++ * of @name for device @device. ++ * ++ * Should be called from user context where sleeping is allowed. ++ * ++ * @name will be used as $FIRMWARE in the uevent environment and ++ * should be distinctive enough not to be confused with any other ++ * firmware image for this or any other device. ++ **/ ++int ++request_firmware(const struct firmware **firmware_p, const char *name, ++ struct device *device) ++{ ++ int uevent = 1; ++ return _request_firmware(firmware_p, name, device, uevent, false); ++} ++ ++/** ++ * release_firmware: - release the resource associated with a firmware image ++ * @fw: firmware resource to release ++ **/ ++void release_firmware(const struct firmware *fw) ++{ ++ if (fw) { ++ if (!fw_is_builtin_firmware(fw)) ++ firmware_free_data(fw); ++ kfree(fw); ++ } ++} ++ ++/* Async support */ ++struct firmware_work { ++ struct work_struct work; ++ struct module *module; ++ const char *name; ++ struct device *device; ++ void *context; ++ void (*cont)(const struct firmware *fw, void *context); ++ int uevent; ++}; ++ ++static int request_firmware_work_func(void *arg) ++{ ++ struct firmware_work *fw_work = arg; ++ const struct firmware *fw; ++ int ret; ++ ++ if (!arg) { ++ WARN_ON(1); ++ return 0; ++ } ++ ++ ret = _request_firmware(&fw, fw_work->name, fw_work->device, ++ fw_work->uevent, true); ++ fw_work->cont(fw, fw_work->context); ++ ++ module_put(fw_work->module); ++ kfree(fw_work); ++ ++ return ret; ++} ++ ++/** ++ * request_firmware_nowait - asynchronous version of request_firmware ++ * @module: module requesting the firmware ++ * @uevent: sends uevent to copy the firmware image if this flag ++ * is non-zero else the firmware copy must be done manually. ++ * @name: name of firmware file ++ * @device: device for which firmware is being loaded ++ * @gfp: allocation flags ++ * @context: will be passed over to @cont, and ++ * @fw may be %NULL if firmware request fails. ++ * @cont: function will be called asynchronously when the firmware ++ * request is over. ++ * ++ * Asynchronous variant of request_firmware() for user contexts where ++ * it is not possible to sleep for long time. It can't be called ++ * in atomic contexts. ++ **/ ++int ++request_firmware_nowait( ++ struct module *module, int uevent, ++ const char *name, struct device *device, gfp_t gfp, void *context, ++ void (*cont)(const struct firmware *fw, void *context)) ++{ ++ struct task_struct *task; ++ struct firmware_work *fw_work; ++ ++ fw_work = kzalloc(sizeof (struct firmware_work), gfp); ++ if (!fw_work) ++ return -ENOMEM; ++ ++ fw_work->module = module; ++ fw_work->name = name; ++ fw_work->device = device; ++ fw_work->context = context; ++ fw_work->cont = cont; ++ fw_work->uevent = uevent; ++ ++ if (!try_module_get(module)) { ++ kfree(fw_work); ++ return -EFAULT; ++ } ++ ++ task = kthread_run(request_firmware_work_func, fw_work, ++ "firmware/%s", name); ++ if (IS_ERR(task)) { ++ fw_work->cont(NULL, fw_work->context); ++ module_put(fw_work->module); ++ kfree(fw_work); ++ return PTR_ERR(task); ++ } ++ ++ return 0; ++} ++ ++static int __init firmware_class_init(void) ++{ ++ return class_register(&firmware_class); ++} ++ ++static void __exit firmware_class_exit(void) ++{ ++ class_unregister(&firmware_class); ++} ++ ++fs_initcall(firmware_class_init); ++module_exit(firmware_class_exit); ++ ++EXPORT_SYMBOL_GPL(release_firmware); ++EXPORT_SYMBOL_GPL(request_firmware); ++EXPORT_SYMBOL_GPL(request_firmware_nowait); diff --cc compat/compat/cordic.c index 000000000000,000000000000..a6340b6a0935 new file mode 100644 --- /dev/null +++ b/compat/compat/cordic.c @@@ -1,0 -1,0 +1,101 @@@ ++/* ++ * Copyright (c) 2011 Broadcom Corporation ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ */ ++#include ++#include ++ ++#define CORDIC_ANGLE_GEN 39797 ++#define CORDIC_PRECISION_SHIFT 16 ++#define CORDIC_NUM_ITER (CORDIC_PRECISION_SHIFT + 2) ++ ++#define FIXED(X) ((s32)((X) << CORDIC_PRECISION_SHIFT)) ++#define FLOAT(X) (((X) >= 0) \ ++ ? ((((X) >> (CORDIC_PRECISION_SHIFT - 1)) + 1) >> 1) \ ++ : -((((-(X)) >> (CORDIC_PRECISION_SHIFT - 1)) + 1) >> 1)) ++ ++static const s32 arctan_table[] = { ++ 2949120, ++ 1740967, ++ 919879, ++ 466945, ++ 234379, ++ 117304, ++ 58666, ++ 29335, ++ 14668, ++ 7334, ++ 3667, ++ 1833, ++ 917, ++ 458, ++ 229, ++ 115, ++ 57, ++ 29 ++}; ++ ++/* ++ * cordic_calc_iq() - calculates the i/q coordinate for given angle ++ * ++ * theta: angle in degrees for which i/q coordinate is to be calculated ++ * coord: function output parameter holding the i/q coordinate ++ */ ++struct cordic_iq cordic_calc_iq(s32 theta) ++{ ++ struct cordic_iq coord; ++ s32 angle, valtmp; ++ unsigned iter; ++ int signx = 1; ++ int signtheta; ++ ++ coord.i = CORDIC_ANGLE_GEN; ++ coord.q = 0; ++ angle = 0; ++ ++ theta = FIXED(theta); ++ signtheta = (theta < 0) ? -1 : 1; ++ theta = ((theta + FIXED(180) * signtheta) % FIXED(360)) - ++ FIXED(180) * signtheta; ++ ++ if (FLOAT(theta) > 90) { ++ theta -= FIXED(180); ++ signx = -1; ++ } else if (FLOAT(theta) < -90) { ++ theta += FIXED(180); ++ signx = -1; ++ } ++ ++ for (iter = 0; iter < CORDIC_NUM_ITER; iter++) { ++ if (theta > angle) { ++ valtmp = coord.i - (coord.q >> iter); ++ coord.q += (coord.i >> iter); ++ angle += arctan_table[iter]; ++ } else { ++ valtmp = coord.i + (coord.q >> iter); ++ coord.q -= (coord.i >> iter); ++ angle -= arctan_table[iter]; ++ } ++ coord.i = valtmp; ++ } ++ ++ coord.i *= signx; ++ coord.q *= signx; ++ return coord; ++} ++EXPORT_SYMBOL_GPL(cordic_calc_iq); ++ ++MODULE_DESCRIPTION("Cordic functions"); ++MODULE_AUTHOR("Broadcom Corporation"); ++MODULE_LICENSE("Dual BSD/GPL"); diff --cc compat/compat/crc8.c index 000000000000,000000000000..5878171c5bd5 new file mode 100644 --- /dev/null +++ b/compat/compat/crc8.c @@@ -1,0 -1,0 +1,87 @@@ ++/* ++ * Copyright (c) 2011 Broadcom Corporation ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ */ ++ ++#undef pr_fmt ++#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt ++ ++#include ++#include ++#include ++ ++/* ++ * crc8_populate_msb - fill crc table for given polynomial in reverse bit order. ++ * ++ * table: table to be filled. ++ * polynomial: polynomial for which table is to be filled. ++ */ ++void crc8_populate_msb(u8 table[CRC8_TABLE_SIZE], u8 polynomial) ++{ ++ int i, j; ++ const u8 msbit = 0x80; ++ u8 t = msbit; ++ ++ table[0] = 0; ++ ++ for (i = 1; i < CRC8_TABLE_SIZE; i *= 2) { ++ t = (t << 1) ^ (t & msbit ? polynomial : 0); ++ for (j = 0; j < i; j++) ++ table[i+j] = table[j] ^ t; ++ } ++} ++EXPORT_SYMBOL_GPL(crc8_populate_msb); ++ ++/* ++ * crc8_populate_lsb - fill crc table for given polynomial in regular bit order. ++ * ++ * table: table to be filled. ++ * polynomial: polynomial for which table is to be filled. ++ */ ++void crc8_populate_lsb(u8 table[CRC8_TABLE_SIZE], u8 polynomial) ++{ ++ int i, j; ++ u8 t = 1; ++ ++ table[0] = 0; ++ ++ for (i = (CRC8_TABLE_SIZE >> 1); i; i >>= 1) { ++ t = (t >> 1) ^ (t & 1 ? polynomial : 0); ++ for (j = 0; j < CRC8_TABLE_SIZE; j += 2*i) ++ table[i+j] = table[j] ^ t; ++ } ++} ++EXPORT_SYMBOL_GPL(crc8_populate_lsb); ++ ++/* ++ * crc8 - calculate a crc8 over the given input data. ++ * ++ * table: crc table used for calculation. ++ * pdata: pointer to data buffer. ++ * nbytes: number of bytes in data buffer. ++ * crc: previous returned crc8 value. ++ */ ++u8 crc8(const u8 table[CRC8_TABLE_SIZE], u8 *pdata, size_t nbytes, u8 crc) ++{ ++ /* loop over the buffer data */ ++ while (nbytes-- > 0) ++ crc = table[(crc ^ *pdata++) & 0xff]; ++ ++ return crc; ++} ++EXPORT_SYMBOL_GPL(crc8); ++ ++MODULE_DESCRIPTION("CRC8 (by Williams, Ross N.) function"); ++MODULE_AUTHOR("Broadcom Corporation"); ++MODULE_LICENSE("Dual BSD/GPL"); diff --cc compat/compat/flow_dissector.c index 000000000000,000000000000..7dd7ec191506 new file mode 100644 --- /dev/null +++ b/compat/compat/flow_dissector.c @@@ -1,0 -1,0 +1,143 @@@ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* copy saddr & daddr, possibly using 64bit load/store ++ * Equivalent to : flow->src = iph->saddr; ++ * flow->dst = iph->daddr; ++ */ ++static void iph_to_flow_copy_addrs(struct flow_keys *flow, const struct iphdr *iph) ++{ ++ BUILD_BUG_ON(offsetof(typeof(*flow), dst) != ++ offsetof(typeof(*flow), src) + sizeof(flow->src)); ++ memcpy(&flow->src, &iph->saddr, sizeof(flow->src) + sizeof(flow->dst)); ++} ++ ++bool skb_flow_dissect(const struct sk_buff *skb, struct flow_keys *flow) ++{ ++ int poff, nhoff = skb_network_offset(skb); ++ u8 ip_proto; ++ __be16 proto = skb->protocol; ++ ++ memset(flow, 0, sizeof(*flow)); ++ ++again: ++ switch (proto) { ++ case __constant_htons(ETH_P_IP): { ++ const struct iphdr *iph; ++ struct iphdr _iph; ++ip: ++ iph = skb_header_pointer(skb, nhoff, sizeof(_iph), &_iph); ++ if (!iph) ++ return false; ++ ++ if (ip_is_fragment(iph)) ++ ip_proto = 0; ++ else ++ ip_proto = iph->protocol; ++ iph_to_flow_copy_addrs(flow, iph); ++ nhoff += iph->ihl * 4; ++ break; ++ } ++ case __constant_htons(ETH_P_IPV6): { ++ const struct ipv6hdr *iph; ++ struct ipv6hdr _iph; ++ipv6: ++ iph = skb_header_pointer(skb, nhoff, sizeof(_iph), &_iph); ++ if (!iph) ++ return false; ++ ++ ip_proto = iph->nexthdr; ++ flow->src = iph->saddr.s6_addr32[3]; ++ flow->dst = iph->daddr.s6_addr32[3]; ++ nhoff += sizeof(struct ipv6hdr); ++ break; ++ } ++ case __constant_htons(ETH_P_8021Q): { ++ const struct vlan_hdr *vlan; ++ struct vlan_hdr _vlan; ++ ++ vlan = skb_header_pointer(skb, nhoff, sizeof(_vlan), &_vlan); ++ if (!vlan) ++ return false; ++ ++ proto = vlan->h_vlan_encapsulated_proto; ++ nhoff += sizeof(*vlan); ++ goto again; ++ } ++ case __constant_htons(ETH_P_PPP_SES): { ++ struct { ++ struct pppoe_hdr hdr; ++ __be16 proto; ++ } *hdr, _hdr; ++ hdr = skb_header_pointer(skb, nhoff, sizeof(_hdr), &_hdr); ++ if (!hdr) ++ return false; ++ proto = hdr->proto; ++ nhoff += PPPOE_SES_HLEN; ++ switch (proto) { ++ case __constant_htons(PPP_IP): ++ goto ip; ++ case __constant_htons(PPP_IPV6): ++ goto ipv6; ++ default: ++ return false; ++ } ++ } ++ default: ++ return false; ++ } ++ ++ switch (ip_proto) { ++ case IPPROTO_GRE: { ++ struct gre_hdr { ++ __be16 flags; ++ __be16 proto; ++ } *hdr, _hdr; ++ ++ hdr = skb_header_pointer(skb, nhoff, sizeof(_hdr), &_hdr); ++ if (!hdr) ++ return false; ++ /* ++ * Only look inside GRE if version zero and no ++ * routing ++ */ ++ if (!(hdr->flags & (GRE_VERSION|GRE_ROUTING))) { ++ proto = hdr->proto; ++ nhoff += 4; ++ if (hdr->flags & GRE_CSUM) ++ nhoff += 4; ++ if (hdr->flags & GRE_KEY) ++ nhoff += 4; ++ if (hdr->flags & GRE_SEQ) ++ nhoff += 4; ++ goto again; ++ } ++ break; ++ } ++ case IPPROTO_IPIP: ++ goto again; ++ default: ++ break; ++ } ++ ++ flow->ip_proto = ip_proto; ++ poff = proto_ports_offset(ip_proto); ++ if (poff >= 0) { ++ __be32 *ports, _ports; ++ ++ nhoff += poff; ++ ports = skb_header_pointer(skb, nhoff, sizeof(_ports), &_ports); ++ if (ports) ++ flow->ports = *ports; ++ } ++ ++ return true; ++} diff --cc compat/compat/hid-ids.h index 000000000000,000000000000..c147dc06f8cd new file mode 100644 --- /dev/null +++ b/compat/compat/hid-ids.h @@@ -1,0 -1,0 +1,866 @@@ ++/* ++ * USB HID quirks support for Linux ++ * ++ * Copyright (c) 1999 Andreas Gal ++ * Copyright (c) 2000-2005 Vojtech Pavlik ++ * Copyright (c) 2005 Michael Haboustak for Concept2, Inc ++ * Copyright (c) 2006-2007 Jiri Kosina ++ */ ++ ++/* ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the Free ++ * Software Foundation; either version 2 of the License, or (at your option) ++ * any later version. ++ */ ++ ++#ifndef HID_IDS_H_FILE ++#define HID_IDS_H_FILE ++ ++#define USB_VENDOR_ID_3M 0x0596 ++#define USB_DEVICE_ID_3M1968 0x0500 ++#define USB_DEVICE_ID_3M2256 0x0502 ++#define USB_DEVICE_ID_3M3266 0x0506 ++ ++#define USB_VENDOR_ID_A4TECH 0x09da ++#define USB_DEVICE_ID_A4TECH_WCP32PU 0x0006 ++#define USB_DEVICE_ID_A4TECH_X5_005D 0x000a ++#define USB_DEVICE_ID_A4TECH_RP_649 0x001a ++ ++#define USB_VENDOR_ID_AASHIMA 0x06d6 ++#define USB_DEVICE_ID_AASHIMA_GAMEPAD 0x0025 ++#define USB_DEVICE_ID_AASHIMA_PREDATOR 0x0026 ++ ++#define USB_VENDOR_ID_ACECAD 0x0460 ++#define USB_DEVICE_ID_ACECAD_FLAIR 0x0004 ++#define USB_DEVICE_ID_ACECAD_302 0x0008 ++ ++#define USB_VENDOR_ID_ACRUX 0x1a34 ++ ++#define USB_VENDOR_ID_ACTIONSTAR 0x2101 ++#define USB_DEVICE_ID_ACTIONSTAR_1011 0x1011 ++ ++#define USB_VENDOR_ID_ADS_TECH 0x06e1 ++#define USB_DEVICE_ID_ADS_TECH_RADIO_SI470X 0xa155 ++ ++#define USB_VENDOR_ID_AFATECH 0x15a4 ++#define USB_DEVICE_ID_AFATECH_AF9016 0x9016 ++ ++#define USB_VENDOR_ID_AIPTEK 0x08ca ++#define USB_DEVICE_ID_AIPTEK_01 0x0001 ++#define USB_DEVICE_ID_AIPTEK_10 0x0010 ++#define USB_DEVICE_ID_AIPTEK_20 0x0020 ++#define USB_DEVICE_ID_AIPTEK_21 0x0021 ++#define USB_DEVICE_ID_AIPTEK_22 0x0022 ++#define USB_DEVICE_ID_AIPTEK_23 0x0023 ++#define USB_DEVICE_ID_AIPTEK_24 0x0024 ++ ++#define USB_VENDOR_ID_AIRCABLE 0x16CA ++#define USB_DEVICE_ID_AIRCABLE1 0x1502 ++ ++#define USB_VENDOR_ID_AIREN 0x1a2c ++#define USB_DEVICE_ID_AIREN_SLIMPLUS 0x0002 ++ ++#define USB_VENDOR_ID_ALCOR 0x058f ++#define USB_DEVICE_ID_ALCOR_USBRS232 0x9720 ++ ++#define USB_VENDOR_ID_ALPS 0x0433 ++#define USB_DEVICE_ID_IBM_GAMEPAD 0x1101 ++ ++#define USB_VENDOR_ID_APPLE 0x05ac ++#define USB_DEVICE_ID_APPLE_MIGHTYMOUSE 0x0304 ++#define USB_DEVICE_ID_APPLE_MAGICMOUSE 0x030d ++#define USB_DEVICE_ID_APPLE_MAGICTRACKPAD 0x030e ++#define USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI 0x020e ++#define USB_DEVICE_ID_APPLE_FOUNTAIN_ISO 0x020f ++#define USB_DEVICE_ID_APPLE_GEYSER_ANSI 0x0214 ++#define USB_DEVICE_ID_APPLE_GEYSER_ISO 0x0215 ++#define USB_DEVICE_ID_APPLE_GEYSER_JIS 0x0216 ++#define USB_DEVICE_ID_APPLE_GEYSER3_ANSI 0x0217 ++#define USB_DEVICE_ID_APPLE_GEYSER3_ISO 0x0218 ++#define USB_DEVICE_ID_APPLE_GEYSER3_JIS 0x0219 ++#define USB_DEVICE_ID_APPLE_GEYSER4_ANSI 0x021a ++#define USB_DEVICE_ID_APPLE_GEYSER4_ISO 0x021b ++#define USB_DEVICE_ID_APPLE_GEYSER4_JIS 0x021c ++#define USB_DEVICE_ID_APPLE_ALU_MINI_ANSI 0x021d ++#define USB_DEVICE_ID_APPLE_ALU_MINI_ISO 0x021e ++#define USB_DEVICE_ID_APPLE_ALU_MINI_JIS 0x021f ++#define USB_DEVICE_ID_APPLE_ALU_ANSI 0x0220 ++#define USB_DEVICE_ID_APPLE_ALU_ISO 0x0221 ++#define USB_DEVICE_ID_APPLE_ALU_JIS 0x0222 ++#define USB_DEVICE_ID_APPLE_WELLSPRING_ANSI 0x0223 ++#define USB_DEVICE_ID_APPLE_WELLSPRING_ISO 0x0224 ++#define USB_DEVICE_ID_APPLE_WELLSPRING_JIS 0x0225 ++#define USB_DEVICE_ID_APPLE_GEYSER4_HF_ANSI 0x0229 ++#define USB_DEVICE_ID_APPLE_GEYSER4_HF_ISO 0x022a ++#define USB_DEVICE_ID_APPLE_GEYSER4_HF_JIS 0x022b ++#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI 0x022c ++#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_ISO 0x022d ++#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS 0x022e ++#define USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI 0x0230 ++#define USB_DEVICE_ID_APPLE_WELLSPRING2_ISO 0x0231 ++#define USB_DEVICE_ID_APPLE_WELLSPRING2_JIS 0x0232 ++#define USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI 0x0236 ++#define USB_DEVICE_ID_APPLE_WELLSPRING3_ISO 0x0237 ++#define USB_DEVICE_ID_APPLE_WELLSPRING3_JIS 0x0238 ++#define USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI 0x023f ++#define USB_DEVICE_ID_APPLE_WELLSPRING4_ISO 0x0240 ++#define USB_DEVICE_ID_APPLE_WELLSPRING4_JIS 0x0241 ++#define USB_DEVICE_ID_APPLE_WELLSPRING4A_ANSI 0x0242 ++#define USB_DEVICE_ID_APPLE_WELLSPRING4A_ISO 0x0243 ++#define USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS 0x0244 ++#define USB_DEVICE_ID_APPLE_WELLSPRING5_ANSI 0x0245 ++#define USB_DEVICE_ID_APPLE_WELLSPRING5_ISO 0x0246 ++#define USB_DEVICE_ID_APPLE_WELLSPRING5_JIS 0x0247 ++#define USB_DEVICE_ID_APPLE_ALU_REVB_ANSI 0x024f ++#define USB_DEVICE_ID_APPLE_ALU_REVB_ISO 0x0250 ++#define USB_DEVICE_ID_APPLE_ALU_REVB_JIS 0x0251 ++#define USB_DEVICE_ID_APPLE_WELLSPRING5A_ANSI 0x0252 ++#define USB_DEVICE_ID_APPLE_WELLSPRING5A_ISO 0x0253 ++#define USB_DEVICE_ID_APPLE_WELLSPRING5A_JIS 0x0254 ++#define USB_DEVICE_ID_APPLE_WELLSPRING7A_ANSI 0x0259 ++#define USB_DEVICE_ID_APPLE_WELLSPRING7A_ISO 0x025a ++#define USB_DEVICE_ID_APPLE_WELLSPRING7A_JIS 0x025b ++#define USB_DEVICE_ID_APPLE_WELLSPRING6A_ANSI 0x0249 ++#define USB_DEVICE_ID_APPLE_WELLSPRING6A_ISO 0x024a ++#define USB_DEVICE_ID_APPLE_WELLSPRING6A_JIS 0x024b ++#define USB_DEVICE_ID_APPLE_WELLSPRING6_ANSI 0x024c ++#define USB_DEVICE_ID_APPLE_WELLSPRING6_ISO 0x024d ++#define USB_DEVICE_ID_APPLE_WELLSPRING6_JIS 0x024e ++#define USB_DEVICE_ID_APPLE_WELLSPRING7_ANSI 0x0262 ++#define USB_DEVICE_ID_APPLE_WELLSPRING7_ISO 0x0263 ++#define USB_DEVICE_ID_APPLE_WELLSPRING7_JIS 0x0264 ++#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI 0x0239 ++#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO 0x023a ++#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS 0x023b ++#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ANSI 0x0255 ++#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ISO 0x0256 ++#define USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY 0x030a ++#define USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY 0x030b ++#define USB_DEVICE_ID_APPLE_ATV_IRCONTROL 0x8241 ++#define USB_DEVICE_ID_APPLE_IRCONTROL4 0x8242 ++ ++#define USB_VENDOR_ID_ASUS 0x0486 ++#define USB_DEVICE_ID_ASUS_T91MT 0x0185 ++#define USB_DEVICE_ID_ASUSTEK_MULTITOUCH_YFO 0x0186 ++ ++#define USB_VENDOR_ID_ASUSTEK 0x0b05 ++#define USB_DEVICE_ID_ASUSTEK_LCM 0x1726 ++#define USB_DEVICE_ID_ASUSTEK_LCM2 0x175b ++ ++#define USB_VENDOR_ID_ATEN 0x0557 ++#define USB_DEVICE_ID_ATEN_UC100KM 0x2004 ++#define USB_DEVICE_ID_ATEN_CS124U 0x2202 ++#define USB_DEVICE_ID_ATEN_2PORTKVM 0x2204 ++#define USB_DEVICE_ID_ATEN_4PORTKVM 0x2205 ++#define USB_DEVICE_ID_ATEN_4PORTKVMC 0x2208 ++ ++#define USB_VENDOR_ID_ATMEL 0x03eb ++#define USB_DEVICE_ID_ATMEL_MULTITOUCH 0x211c ++#define USB_DEVICE_ID_ATMEL_MXT_DIGITIZER 0x2118 ++ ++#define USB_VENDOR_ID_AUREAL 0x0755 ++#define USB_DEVICE_ID_AUREAL_W01RN 0x2626 ++ ++#define USB_VENDOR_ID_AVERMEDIA 0x07ca ++#define USB_DEVICE_ID_AVER_FM_MR800 0xb800 ++ ++#define USB_VENDOR_ID_AXENTIA 0x12cf ++#define USB_DEVICE_ID_AXENTIA_FM_RADIO 0x7111 ++ ++#define USB_VENDOR_ID_BAANTO 0x2453 ++#define USB_DEVICE_ID_BAANTO_MT_190W2 0x0100 ++ ++#define USB_VENDOR_ID_BELKIN 0x050d ++#define USB_DEVICE_ID_FLIP_KVM 0x3201 ++ ++#define USB_VENDOR_ID_BERKSHIRE 0x0c98 ++#define USB_DEVICE_ID_BERKSHIRE_PCWD 0x1140 ++ ++#define USB_VENDOR_ID_BTC 0x046e ++#define USB_DEVICE_ID_BTC_EMPREX_REMOTE 0x5578 ++#define USB_DEVICE_ID_BTC_EMPREX_REMOTE_2 0x5577 ++ ++#define USB_VENDOR_ID_CANDO 0x2087 ++#define USB_DEVICE_ID_CANDO_PIXCIR_MULTI_TOUCH 0x0703 ++#define USB_DEVICE_ID_CANDO_MULTI_TOUCH 0x0a01 ++#define USB_DEVICE_ID_CANDO_MULTI_TOUCH_10_1 0x0a02 ++#define USB_DEVICE_ID_CANDO_MULTI_TOUCH_11_6 0x0b03 ++#define USB_DEVICE_ID_CANDO_MULTI_TOUCH_15_6 0x0f01 ++ ++#define USB_VENDOR_ID_CH 0x068e ++#define USB_DEVICE_ID_CH_PRO_THROTTLE 0x00f1 ++#define USB_DEVICE_ID_CH_PRO_PEDALS 0x00f2 ++#define USB_DEVICE_ID_CH_FIGHTERSTICK 0x00f3 ++#define USB_DEVICE_ID_CH_COMBATSTICK 0x00f4 ++#define USB_DEVICE_ID_CH_FLIGHT_SIM_ECLIPSE_YOKE 0x0051 ++#define USB_DEVICE_ID_CH_FLIGHT_SIM_YOKE 0x00ff ++#define USB_DEVICE_ID_CH_3AXIS_5BUTTON_STICK 0x00d3 ++#define USB_DEVICE_ID_CH_AXIS_295 0x001c ++ ++#define USB_VENDOR_ID_CHERRY 0x046a ++#define USB_DEVICE_ID_CHERRY_CYMOTION 0x0023 ++#define USB_DEVICE_ID_CHERRY_CYMOTION_SOLAR 0x0027 ++ ++#define USB_VENDOR_ID_CHIC 0x05fe ++#define USB_DEVICE_ID_CHIC_GAMEPAD 0x0014 ++ ++#define USB_VENDOR_ID_CHICONY 0x04f2 ++#define USB_DEVICE_ID_CHICONY_TACTICAL_PAD 0x0418 ++#define USB_DEVICE_ID_CHICONY_MULTI_TOUCH 0xb19d ++#define USB_DEVICE_ID_CHICONY_WIRELESS 0x0618 ++#define USB_DEVICE_ID_CHICONY_WIRELESS2 0x1123 ++#define USB_DEVICE_ID_CHICONY_AK1D 0x1125 ++ ++#define USB_VENDOR_ID_CHUNGHWAT 0x2247 ++#define USB_DEVICE_ID_CHUNGHWAT_MULTITOUCH 0x0001 ++ ++#define USB_VENDOR_ID_CIDC 0x1677 ++ ++#define USB_VENDOR_ID_CMEDIA 0x0d8c ++#define USB_DEVICE_ID_CM109 0x000e ++ ++#define USB_VENDOR_ID_CODEMERCS 0x07c0 ++#define USB_DEVICE_ID_CODEMERCS_IOW_FIRST 0x1500 ++#define USB_DEVICE_ID_CODEMERCS_IOW_LAST 0x15ff ++ ++#define USB_VENDOR_ID_CREATIVELABS 0x041e ++#define USB_DEVICE_ID_PRODIKEYS_PCMIDI 0x2801 ++ ++#define USB_VENDOR_ID_CVTOUCH 0x1ff7 ++#define USB_DEVICE_ID_CVTOUCH_SCREEN 0x0013 ++ ++#define USB_VENDOR_ID_CYGNAL 0x10c4 ++#define USB_DEVICE_ID_CYGNAL_RADIO_SI470X 0x818a ++ ++#define USB_VENDOR_ID_CYPRESS 0x04b4 ++#define USB_DEVICE_ID_CYPRESS_MOUSE 0x0001 ++#define USB_DEVICE_ID_CYPRESS_HIDCOM 0x5500 ++#define USB_DEVICE_ID_CYPRESS_ULTRAMOUSE 0x7417 ++#define USB_DEVICE_ID_CYPRESS_BARCODE_1 0xde61 ++#define USB_DEVICE_ID_CYPRESS_BARCODE_2 0xde64 ++#define USB_DEVICE_ID_CYPRESS_BARCODE_3 0xbca1 ++#define USB_DEVICE_ID_CYPRESS_BARCODE_4 0xed81 ++#define USB_DEVICE_ID_CYPRESS_TRUETOUCH 0xc001 ++ ++#define USB_VENDOR_ID_DEALEXTREAME 0x10c5 ++#define USB_DEVICE_ID_DEALEXTREAME_RADIO_SI4701 0x819a ++ ++#define USB_VENDOR_ID_DELORME 0x1163 ++#define USB_DEVICE_ID_DELORME_EARTHMATE 0x0100 ++#define USB_DEVICE_ID_DELORME_EM_LT20 0x0200 ++ ++#define USB_VENDOR_ID_DMI 0x0c0b ++#define USB_DEVICE_ID_DMI_ENC 0x5fab ++ ++#define USB_VENDOR_ID_DRAGONRISE 0x0079 ++ ++#define USB_VENDOR_ID_DWAV 0x0eef ++#define USB_DEVICE_ID_EGALAX_TOUCHCONTROLLER 0x0001 ++#define USB_DEVICE_ID_DWAV_TOUCHCONTROLLER 0x0002 ++#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_480D 0x480d ++#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_480E 0x480e ++#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7207 0x7207 ++#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_720C 0x720c ++#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7224 0x7224 ++#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_722A 0x722A ++#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_725E 0x725e ++#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7262 0x7262 ++#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_726B 0x726b ++#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72AA 0x72aa ++#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72A1 0x72a1 ++#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72FA 0x72fa ++#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7302 0x7302 ++#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7349 0x7349 ++#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_73F7 0x73f7 ++#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_A001 0xa001 ++#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7224 0x7224 ++#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72D0 0x72d0 ++#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72C4 0x72c4 ++ ++#define USB_VENDOR_ID_ELECOM 0x056e ++#define USB_DEVICE_ID_ELECOM_BM084 0x0061 ++ ++#define USB_VENDOR_ID_DREAM_CHEEKY 0x1d34 ++ ++#define USB_VENDOR_ID_ELO 0x04E7 ++#define USB_DEVICE_ID_ELO_TS2515 0x0022 ++#define USB_DEVICE_ID_ELO_TS2700 0x0020 ++ ++#define USB_VENDOR_ID_EMS 0x2006 ++#define USB_DEVICE_ID_EMS_TRIO_LINKER_PLUS_II 0x0118 ++ ++#define USB_VENDOR_ID_FLATFROG 0x25b5 ++#define USB_DEVICE_ID_MULTITOUCH_3200 0x0002 ++ ++#define USB_VENDOR_ID_ESSENTIAL_REALITY 0x0d7f ++#define USB_DEVICE_ID_ESSENTIAL_REALITY_P5 0x0100 ++ ++#define USB_VENDOR_ID_ETT 0x0664 ++#define USB_DEVICE_ID_TC5UH 0x0309 ++#define USB_DEVICE_ID_TC4UM 0x0306 ++ ++#define USB_VENDOR_ID_ETURBOTOUCH 0x22b9 ++#define USB_DEVICE_ID_ETURBOTOUCH 0x0006 ++ ++#define USB_VENDOR_ID_EZKEY 0x0518 ++#define USB_DEVICE_ID_BTC_8193 0x0002 ++ ++#define USB_VENDOR_ID_FREESCALE 0x15A2 ++#define USB_DEVICE_ID_FREESCALE_MX28 0x004F ++ ++#define USB_VENDOR_ID_FRUCTEL 0x25B6 ++#define USB_DEVICE_ID_GAMETEL_MT_MODE 0x0002 ++ ++#define USB_VENDOR_ID_GAMERON 0x0810 ++#define USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR 0x0001 ++#define USB_DEVICE_ID_GAMERON_DUAL_PCS_ADAPTOR 0x0002 ++ ++#define USB_VENDOR_ID_GENERAL_TOUCH 0x0dfc ++#define USB_DEVICE_ID_GENERAL_TOUCH_WIN7_TWOFINGERS 0x0003 ++#define USB_DEVICE_ID_GENERAL_TOUCH_WIN8_PWT_TENFINGERS 0x0100 ++ ++#define USB_VENDOR_ID_GLAB 0x06c2 ++#define USB_DEVICE_ID_4_PHIDGETSERVO_30 0x0038 ++#define USB_DEVICE_ID_1_PHIDGETSERVO_30 0x0039 ++#define USB_DEVICE_ID_0_0_4_IF_KIT 0x0040 ++#define USB_DEVICE_ID_0_16_16_IF_KIT 0x0044 ++#define USB_DEVICE_ID_8_8_8_IF_KIT 0x0045 ++#define USB_DEVICE_ID_0_8_7_IF_KIT 0x0051 ++#define USB_DEVICE_ID_0_8_8_IF_KIT 0x0053 ++#define USB_DEVICE_ID_PHIDGET_MOTORCONTROL 0x0058 ++ ++#define USB_VENDOR_ID_GOODTOUCH 0x1aad ++#define USB_DEVICE_ID_GOODTOUCH_000f 0x000f ++ ++#define USB_VENDOR_ID_GOTOP 0x08f2 ++#define USB_DEVICE_ID_SUPER_Q2 0x007f ++#define USB_DEVICE_ID_GOGOPEN 0x00ce ++#define USB_DEVICE_ID_PENPOWER 0x00f4 ++ ++#define USB_VENDOR_ID_GREENASIA 0x0e8f ++#define USB_DEVICE_ID_GREENASIA_DUAL_USB_JOYPAD 0x3013 ++ ++#define USB_VENDOR_ID_GRETAGMACBETH 0x0971 ++#define USB_DEVICE_ID_GRETAGMACBETH_HUEY 0x2005 ++ ++#define USB_VENDOR_ID_GRIFFIN 0x077d ++#define USB_DEVICE_ID_POWERMATE 0x0410 ++#define USB_DEVICE_ID_SOUNDKNOB 0x04AA ++#define USB_DEVICE_ID_RADIOSHARK 0x627a ++ ++#define USB_VENDOR_ID_GTCO 0x078c ++#define USB_DEVICE_ID_GTCO_90 0x0090 ++#define USB_DEVICE_ID_GTCO_100 0x0100 ++#define USB_DEVICE_ID_GTCO_101 0x0101 ++#define USB_DEVICE_ID_GTCO_103 0x0103 ++#define USB_DEVICE_ID_GTCO_104 0x0104 ++#define USB_DEVICE_ID_GTCO_105 0x0105 ++#define USB_DEVICE_ID_GTCO_106 0x0106 ++#define USB_DEVICE_ID_GTCO_107 0x0107 ++#define USB_DEVICE_ID_GTCO_108 0x0108 ++#define USB_DEVICE_ID_GTCO_200 0x0200 ++#define USB_DEVICE_ID_GTCO_201 0x0201 ++#define USB_DEVICE_ID_GTCO_202 0x0202 ++#define USB_DEVICE_ID_GTCO_203 0x0203 ++#define USB_DEVICE_ID_GTCO_204 0x0204 ++#define USB_DEVICE_ID_GTCO_205 0x0205 ++#define USB_DEVICE_ID_GTCO_206 0x0206 ++#define USB_DEVICE_ID_GTCO_207 0x0207 ++#define USB_DEVICE_ID_GTCO_300 0x0300 ++#define USB_DEVICE_ID_GTCO_301 0x0301 ++#define USB_DEVICE_ID_GTCO_302 0x0302 ++#define USB_DEVICE_ID_GTCO_303 0x0303 ++#define USB_DEVICE_ID_GTCO_304 0x0304 ++#define USB_DEVICE_ID_GTCO_305 0x0305 ++#define USB_DEVICE_ID_GTCO_306 0x0306 ++#define USB_DEVICE_ID_GTCO_307 0x0307 ++#define USB_DEVICE_ID_GTCO_308 0x0308 ++#define USB_DEVICE_ID_GTCO_309 0x0309 ++#define USB_DEVICE_ID_GTCO_400 0x0400 ++#define USB_DEVICE_ID_GTCO_401 0x0401 ++#define USB_DEVICE_ID_GTCO_402 0x0402 ++#define USB_DEVICE_ID_GTCO_403 0x0403 ++#define USB_DEVICE_ID_GTCO_404 0x0404 ++#define USB_DEVICE_ID_GTCO_405 0x0405 ++#define USB_DEVICE_ID_GTCO_500 0x0500 ++#define USB_DEVICE_ID_GTCO_501 0x0501 ++#define USB_DEVICE_ID_GTCO_502 0x0502 ++#define USB_DEVICE_ID_GTCO_503 0x0503 ++#define USB_DEVICE_ID_GTCO_504 0x0504 ++#define USB_DEVICE_ID_GTCO_1000 0x1000 ++#define USB_DEVICE_ID_GTCO_1001 0x1001 ++#define USB_DEVICE_ID_GTCO_1002 0x1002 ++#define USB_DEVICE_ID_GTCO_1003 0x1003 ++#define USB_DEVICE_ID_GTCO_1004 0x1004 ++#define USB_DEVICE_ID_GTCO_1005 0x1005 ++#define USB_DEVICE_ID_GTCO_1006 0x1006 ++#define USB_DEVICE_ID_GTCO_1007 0x1007 ++ ++#define USB_VENDOR_ID_GYRATION 0x0c16 ++#define USB_DEVICE_ID_GYRATION_REMOTE 0x0002 ++#define USB_DEVICE_ID_GYRATION_REMOTE_2 0x0003 ++#define USB_DEVICE_ID_GYRATION_REMOTE_3 0x0008 ++ ++#define USB_VENDOR_ID_HANWANG 0x0b57 ++#define USB_DEVICE_ID_HANWANG_TABLET_FIRST 0x5000 ++#define USB_DEVICE_ID_HANWANG_TABLET_LAST 0x8fff ++ ++#define USB_VENDOR_ID_HANVON 0x20b3 ++#define USB_DEVICE_ID_HANVON_MULTITOUCH 0x0a18 ++ ++#define USB_VENDOR_ID_HANVON_ALT 0x22ed ++#define USB_DEVICE_ID_HANVON_ALT_MULTITOUCH 0x1010 ++ ++#define USB_VENDOR_ID_HAPP 0x078b ++#define USB_DEVICE_ID_UGCI_DRIVING 0x0010 ++#define USB_DEVICE_ID_UGCI_FLYING 0x0020 ++#define USB_DEVICE_ID_UGCI_FIGHTING 0x0030 ++ ++#define USB_VENDOR_ID_IDEACOM 0x1cb6 ++#define USB_DEVICE_ID_IDEACOM_IDC6650 0x6650 ++#define USB_DEVICE_ID_IDEACOM_IDC6651 0x6651 ++ ++#define USB_VENDOR_ID_ILITEK 0x222a ++#define USB_DEVICE_ID_ILITEK_MULTITOUCH 0x0001 ++ ++#define USB_VENDOR_ID_ION 0x15e4 ++#define USB_DEVICE_ID_ICADE 0x0132 ++ ++#define USB_VENDOR_ID_HOLTEK 0x1241 ++#define USB_DEVICE_ID_HOLTEK_ON_LINE_GRIP 0x5015 ++ ++#define USB_VENDOR_ID_HOLTEK_ALT 0x04d9 ++#define USB_DEVICE_ID_HOLTEK_ALT_KEYBOARD 0xa055 ++ ++#define USB_VENDOR_ID_IMATION 0x0718 ++#define USB_DEVICE_ID_DISC_STAKKA 0xd000 ++ ++#define USB_VENDOR_ID_INTEL_8086 0x8086 ++#define USB_VENDOR_ID_INTEL_8087 0x8087 ++#define USB_DEVICE_ID_SENSOR_HUB_1020 0x1020 ++#define USB_DEVICE_ID_SENSOR_HUB_09FA 0x09FA ++ ++#define USB_VENDOR_ID_IRTOUCHSYSTEMS 0x6615 ++#define USB_DEVICE_ID_IRTOUCH_INFRARED_USB 0x0070 ++ ++#define USB_VENDOR_ID_JESS 0x0c45 ++#define USB_DEVICE_ID_JESS_YUREX 0x1010 ++ ++#define USB_VENDOR_ID_KBGEAR 0x084e ++#define USB_DEVICE_ID_KBGEAR_JAMSTUDIO 0x1001 ++ ++#define USB_VENDOR_ID_KENSINGTON 0x047d ++#define USB_DEVICE_ID_KS_SLIMBLADE 0x2041 ++ ++#define USB_VENDOR_ID_KWORLD 0x1b80 ++#define USB_DEVICE_ID_KWORLD_RADIO_FM700 0xd700 ++ ++#define USB_VENDOR_ID_KEYTOUCH 0x0926 ++#define USB_DEVICE_ID_KEYTOUCH_IEC 0x3333 ++ ++#define USB_VENDOR_ID_KYE 0x0458 ++#define USB_DEVICE_ID_KYE_ERGO_525V 0x0087 ++#define USB_DEVICE_ID_KYE_GPEN_560 0x5003 ++#define USB_DEVICE_ID_KYE_EASYPEN_I405X 0x5010 ++#define USB_DEVICE_ID_KYE_MOUSEPEN_I608X 0x5011 ++#define USB_DEVICE_ID_KYE_EASYPEN_M610X 0x5013 ++ ++#define USB_VENDOR_ID_LABTEC 0x1020 ++#define USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD 0x0006 ++ ++#define USB_VENDOR_ID_LCPOWER 0x1241 ++#define USB_DEVICE_ID_LCPOWER_LC1000 0xf767 ++ ++#define USB_VENDOR_ID_LD 0x0f11 ++#define USB_DEVICE_ID_LD_CASSY 0x1000 ++#define USB_DEVICE_ID_LD_CASSY2 0x1001 ++#define USB_DEVICE_ID_LD_POCKETCASSY 0x1010 ++#define USB_DEVICE_ID_LD_POCKETCASSY2 0x1011 ++#define USB_DEVICE_ID_LD_MOBILECASSY 0x1020 ++#define USB_DEVICE_ID_LD_MOBILECASSY2 0x1021 ++#define USB_DEVICE_ID_LD_MICROCASSYVOLTAGE 0x1031 ++#define USB_DEVICE_ID_LD_MICROCASSYCURRENT 0x1032 ++#define USB_DEVICE_ID_LD_MICROCASSYTIME 0x1033 ++#define USB_DEVICE_ID_LD_MICROCASSYTEMPERATURE 0x1035 ++#define USB_DEVICE_ID_LD_MICROCASSYPH 0x1038 ++#define USB_DEVICE_ID_LD_JWM 0x1080 ++#define USB_DEVICE_ID_LD_DMMP 0x1081 ++#define USB_DEVICE_ID_LD_UMIP 0x1090 ++#define USB_DEVICE_ID_LD_UMIC 0x10A0 ++#define USB_DEVICE_ID_LD_UMIB 0x10B0 ++#define USB_DEVICE_ID_LD_XRAY 0x1100 ++#define USB_DEVICE_ID_LD_XRAY2 0x1101 ++#define USB_DEVICE_ID_LD_XRAYCT 0x1110 ++#define USB_DEVICE_ID_LD_VIDEOCOM 0x1200 ++#define USB_DEVICE_ID_LD_MOTOR 0x1210 ++#define USB_DEVICE_ID_LD_COM3LAB 0x2000 ++#define USB_DEVICE_ID_LD_TELEPORT 0x2010 ++#define USB_DEVICE_ID_LD_NETWORKANALYSER 0x2020 ++#define USB_DEVICE_ID_LD_POWERCONTROL 0x2030 ++#define USB_DEVICE_ID_LD_MACHINETEST 0x2040 ++#define USB_DEVICE_ID_LD_MOSTANALYSER 0x2050 ++#define USB_DEVICE_ID_LD_MOSTANALYSER2 0x2051 ++#define USB_DEVICE_ID_LD_ABSESP 0x2060 ++#define USB_DEVICE_ID_LD_AUTODATABUS 0x2070 ++#define USB_DEVICE_ID_LD_MCT 0x2080 ++#define USB_DEVICE_ID_LD_HYBRID 0x2090 ++#define USB_DEVICE_ID_LD_HEATCONTROL 0x20A0 ++ ++#define USB_VENDOR_ID_LENOVO 0x17ef ++#define USB_DEVICE_ID_LENOVO_TPKBD 0x6009 ++ ++#define USB_VENDOR_ID_LG 0x1fd2 ++#define USB_DEVICE_ID_LG_MULTITOUCH 0x0064 ++ ++#define USB_VENDOR_ID_LOGITECH 0x046d ++#define USB_DEVICE_ID_LOGITECH_AUDIOHUB 0x0a0e ++#define USB_DEVICE_ID_LOGITECH_RECEIVER 0xc101 ++#define USB_DEVICE_ID_LOGITECH_HARMONY_FIRST 0xc110 ++#define USB_DEVICE_ID_LOGITECH_HARMONY_LAST 0xc14f ++#define USB_DEVICE_ID_LOGITECH_HARMONY_PS3 0x0306 ++#define USB_DEVICE_ID_LOGITECH_RUMBLEPAD_CORD 0xc20a ++#define USB_DEVICE_ID_LOGITECH_RUMBLEPAD 0xc211 ++#define USB_DEVICE_ID_LOGITECH_EXTREME_3D 0xc215 ++#define USB_DEVICE_ID_LOGITECH_RUMBLEPAD2 0xc218 ++#define USB_DEVICE_ID_LOGITECH_RUMBLEPAD2_2 0xc219 ++#define USB_DEVICE_ID_LOGITECH_WINGMAN_F3D 0xc283 ++#define USB_DEVICE_ID_LOGITECH_FORCE3D_PRO 0xc286 ++#define USB_DEVICE_ID_LOGITECH_FLIGHT_SYSTEM_G940 0xc287 ++#define USB_DEVICE_ID_LOGITECH_WHEEL 0xc294 ++#define USB_DEVICE_ID_LOGITECH_WINGMAN_FFG 0xc293 ++#define USB_DEVICE_ID_LOGITECH_MOMO_WHEEL 0xc295 ++#define USB_DEVICE_ID_LOGITECH_DFP_WHEEL 0xc298 ++#define USB_DEVICE_ID_LOGITECH_G25_WHEEL 0xc299 ++#define USB_DEVICE_ID_LOGITECH_DFGT_WHEEL 0xc29a ++#define USB_DEVICE_ID_LOGITECH_G27_WHEEL 0xc29b ++#define USB_DEVICE_ID_LOGITECH_WII_WHEEL 0xc29c ++#define USB_DEVICE_ID_LOGITECH_ELITE_KBD 0xc30a ++#define USB_DEVICE_ID_S510_RECEIVER 0xc50c ++#define USB_DEVICE_ID_S510_RECEIVER_2 0xc517 ++#define USB_DEVICE_ID_LOGITECH_CORDLESS_DESKTOP_LX500 0xc512 ++#define USB_DEVICE_ID_MX3000_RECEIVER 0xc513 ++#define USB_DEVICE_ID_LOGITECH_UNIFYING_RECEIVER 0xc52b ++#define USB_DEVICE_ID_LOGITECH_UNIFYING_RECEIVER_2 0xc532 ++#define USB_DEVICE_ID_SPACETRAVELLER 0xc623 ++#define USB_DEVICE_ID_SPACENAVIGATOR 0xc626 ++#define USB_DEVICE_ID_DINOVO_DESKTOP 0xc704 ++#define USB_DEVICE_ID_DINOVO_EDGE 0xc714 ++#define USB_DEVICE_ID_DINOVO_MINI 0xc71f ++#define USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2 0xca03 ++ ++#define USB_VENDOR_ID_LUMIO 0x202e ++#define USB_DEVICE_ID_CRYSTALTOUCH 0x0006 ++#define USB_DEVICE_ID_CRYSTALTOUCH_DUAL 0x0007 ++ ++#define USB_VENDOR_ID_MADCATZ 0x0738 ++#define USB_DEVICE_ID_MADCATZ_BEATPAD 0x4540 ++ ++#define USB_VENDOR_ID_MCC 0x09db ++#define USB_DEVICE_ID_MCC_PMD1024LS 0x0076 ++#define USB_DEVICE_ID_MCC_PMD1208LS 0x007a ++ ++#define USB_VENDOR_ID_MGE 0x0463 ++#define USB_DEVICE_ID_MGE_UPS 0xffff ++#define USB_DEVICE_ID_MGE_UPS1 0x0001 ++ ++#define USB_VENDOR_ID_MICROCHIP 0x04d8 ++#define USB_DEVICE_ID_PICKIT1 0x0032 ++#define USB_DEVICE_ID_PICKIT2 0x0033 ++#define USB_DEVICE_ID_PICOLCD 0xc002 ++#define USB_DEVICE_ID_PICOLCD_BOOTLOADER 0xf002 ++ ++#define USB_VENDOR_ID_MICROSOFT 0x045e ++#define USB_DEVICE_ID_SIDEWINDER_GV 0x003b ++#define USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0 0x009d ++#define USB_DEVICE_ID_MS_NE4K 0x00db ++#define USB_DEVICE_ID_MS_LK6K 0x00f9 ++#define USB_DEVICE_ID_MS_PRESENTER_8K_BT 0x0701 ++#define USB_DEVICE_ID_MS_PRESENTER_8K_USB 0x0713 ++#define USB_DEVICE_ID_MS_DIGITAL_MEDIA_3K 0x0730 ++#define USB_DEVICE_ID_MS_COMFORT_MOUSE_4500 0x076c ++ ++#define USB_VENDOR_ID_MOJO 0x8282 ++#define USB_DEVICE_ID_RETRO_ADAPTER 0x3201 ++ ++#define USB_VENDOR_ID_MONTEREY 0x0566 ++#define USB_DEVICE_ID_GENIUS_KB29E 0x3004 ++ ++#define USB_VENDOR_ID_NATIONAL_SEMICONDUCTOR 0x0400 ++#define USB_DEVICE_ID_N_S_HARMONY 0xc359 ++ ++#define USB_VENDOR_ID_NATSU 0x08b7 ++#define USB_DEVICE_ID_NATSU_GAMEPAD 0x0001 ++ ++#define USB_VENDOR_ID_NCR 0x0404 ++#define USB_DEVICE_ID_NCR_FIRST 0x0300 ++#define USB_DEVICE_ID_NCR_LAST 0x03ff ++ ++#define USB_VENDOR_ID_NEC 0x073e ++#define USB_DEVICE_ID_NEC_USB_GAME_PAD 0x0301 ++ ++#define USB_VENDOR_ID_NEXTWINDOW 0x1926 ++#define USB_DEVICE_ID_NEXTWINDOW_TOUCHSCREEN 0x0003 ++ ++#define USB_VENDOR_ID_NINTENDO 0x057e ++#define USB_DEVICE_ID_NINTENDO_WIIMOTE 0x0306 ++ ++#define USB_VENDOR_ID_NOVATEK 0x0603 ++#define USB_DEVICE_ID_NOVATEK_PCT 0x0600 ++ ++#define USB_VENDOR_ID_NTRIG 0x1b96 ++#define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN 0x0001 ++#define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_1 0x0003 ++#define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_2 0x0004 ++#define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_3 0x0005 ++#define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_4 0x0006 ++#define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_5 0x0007 ++#define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_6 0x0008 ++#define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_7 0x0009 ++#define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_8 0x000A ++#define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_9 0x000B ++#define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_10 0x000C ++#define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_11 0x000D ++#define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_12 0x000E ++#define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_13 0x000F ++#define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_14 0x0010 ++#define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_15 0x0011 ++#define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_16 0x0012 ++#define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_17 0x0013 ++#define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_18 0x0014 ++ ++#define USB_VENDOR_ID_ONTRAK 0x0a07 ++#define USB_DEVICE_ID_ONTRAK_ADU100 0x0064 ++ ++#define USB_VENDOR_ID_ORTEK 0x05a4 ++#define USB_DEVICE_ID_ORTEK_PKB1700 0x1700 ++#define USB_DEVICE_ID_ORTEK_WKB2000 0x2000 ++ ++#define USB_VENDOR_ID_PANASONIC 0x04da ++#define USB_DEVICE_ID_PANABOARD_UBT780 0x1044 ++#define USB_DEVICE_ID_PANABOARD_UBT880 0x104d ++ ++#define USB_VENDOR_ID_PANJIT 0x134c ++ ++#define USB_VENDOR_ID_PANTHERLORD 0x0810 ++#define USB_DEVICE_ID_PANTHERLORD_TWIN_USB_JOYSTICK 0x0001 ++ ++#define USB_VENDOR_ID_PENMOUNT 0x14e1 ++#define USB_DEVICE_ID_PENMOUNT_PCI 0x3500 ++ ++#define USB_VENDOR_ID_PETALYNX 0x18b1 ++#define USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE 0x0037 ++ ++#define USB_VENDOR_ID_PHILIPS 0x0471 ++#define USB_DEVICE_ID_PHILIPS_IEEE802154_DONGLE 0x0617 ++ ++#define USB_VENDOR_ID_PI_ENGINEERING 0x05f3 ++#define USB_DEVICE_ID_PI_ENGINEERING_VEC_USB_FOOTPEDAL 0xff ++ ++#define USB_VENDOR_ID_PIXART 0x093a ++#define USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN 0x8001 ++#define USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN1 0x8002 ++#define USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN2 0x8003 ++ ++#define USB_VENDOR_ID_PLAYDOTCOM 0x0b43 ++#define USB_DEVICE_ID_PLAYDOTCOM_EMS_USBII 0x0003 ++ ++#define USB_VENDOR_ID_POWERCOM 0x0d9f ++#define USB_DEVICE_ID_POWERCOM_UPS 0x0002 ++ ++#define USB_VENDOR_ID_PRODIGE 0x05af ++#define USB_DEVICE_ID_PRODIGE_CORDLESS 0x3062 ++ ++#define USB_VENDOR_ID_QUANTA 0x0408 ++#define USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH 0x3000 ++#define USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3001 0x3001 ++#define USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3008 0x3008 ++ ++#define USB_VENDOR_ID_ROCCAT 0x1e7d ++#define USB_DEVICE_ID_ROCCAT_ARVO 0x30d4 ++#define USB_DEVICE_ID_ROCCAT_ISKU 0x319c ++#define USB_DEVICE_ID_ROCCAT_KONE 0x2ced ++#define USB_DEVICE_ID_ROCCAT_KONEPLUS 0x2d51 ++#define USB_DEVICE_ID_ROCCAT_KONEXTD 0x2e22 ++#define USB_DEVICE_ID_ROCCAT_KOVAPLUS 0x2d50 ++#define USB_DEVICE_ID_ROCCAT_LUA 0x2c2e ++#define USB_DEVICE_ID_ROCCAT_PYRA_WIRED 0x2c24 ++#define USB_DEVICE_ID_ROCCAT_PYRA_WIRELESS 0x2cf6 ++#define USB_DEVICE_ID_ROCCAT_SAVU 0x2d5a ++ ++#define USB_VENDOR_ID_SAITEK 0x06a3 ++#define USB_DEVICE_ID_SAITEK_RUMBLEPAD 0xff17 ++#define USB_DEVICE_ID_SAITEK_PS1000 0x0621 ++ ++#define USB_VENDOR_ID_SAMSUNG 0x0419 ++#define USB_DEVICE_ID_SAMSUNG_IR_REMOTE 0x0001 ++#define USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE 0x0600 ++ ++#define USB_VENDOR_ID_SENNHEISER 0x1395 ++#define USB_DEVICE_ID_SENNHEISER_BTD500USB 0x002c ++ ++#define USB_VENDOR_ID_SIGMA_MICRO 0x1c4f ++#define USB_DEVICE_ID_SIGMA_MICRO_KEYBOARD 0x0002 ++ ++#define USB_VENDOR_ID_SIGMATEL 0x066F ++#define USB_DEVICE_ID_SIGMATEL_STMP3780 0x3780 ++ ++#define USB_VENDOR_ID_SKYCABLE 0x1223 ++#define USB_DEVICE_ID_SKYCABLE_WIRELESS_PRESENTER 0x3F07 ++ ++#define USB_VENDOR_ID_SONY 0x054c ++#define USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE 0x024b ++#define USB_DEVICE_ID_SONY_PS3_BDREMOTE 0x0306 ++#define USB_DEVICE_ID_SONY_PS3_CONTROLLER 0x0268 ++#define USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER 0x042f ++ ++#define USB_VENDOR_ID_SOUNDGRAPH 0x15c2 ++#define USB_DEVICE_ID_SOUNDGRAPH_IMON_FIRST 0x0034 ++#define USB_DEVICE_ID_SOUNDGRAPH_IMON_LAST 0x0046 ++ ++#define USB_VENDOR_ID_STANTUM 0x1f87 ++#define USB_DEVICE_ID_MTP 0x0002 ++ ++#define USB_VENDOR_ID_STANTUM_STM 0x0483 ++#define USB_DEVICE_ID_MTP_STM 0x3261 ++#define USB_DEVICE_ID_SENSOR_HUB_7014 0x7014 ++ ++#define USB_VENDOR_ID_STANTUM_SITRONIX 0x1403 ++#define USB_DEVICE_ID_MTP_SITRONIX 0x5001 ++ ++#define USB_VENDOR_ID_SUN 0x0430 ++#define USB_DEVICE_ID_RARITAN_KVM_DONGLE 0xcdab ++ ++#define USB_VENDOR_ID_SUNPLUS 0x04fc ++#define USB_DEVICE_ID_SUNPLUS_WDESKTOP 0x05d8 ++ ++#define USB_VENDOR_ID_SYMBOL 0x05e0 ++#define USB_DEVICE_ID_SYMBOL_SCANNER_1 0x0800 ++#define USB_DEVICE_ID_SYMBOL_SCANNER_2 0x1300 ++ ++#define USB_VENDOR_ID_SYNAPTICS 0x06cb ++#define USB_DEVICE_ID_SYNAPTICS_TP 0x0001 ++#define USB_DEVICE_ID_SYNAPTICS_INT_TP 0x0002 ++#define USB_DEVICE_ID_SYNAPTICS_CPAD 0x0003 ++#define USB_DEVICE_ID_SYNAPTICS_TS 0x0006 ++#define USB_DEVICE_ID_SYNAPTICS_STICK 0x0007 ++#define USB_DEVICE_ID_SYNAPTICS_WP 0x0008 ++#define USB_DEVICE_ID_SYNAPTICS_COMP_TP 0x0009 ++#define USB_DEVICE_ID_SYNAPTICS_WTP 0x0010 ++#define USB_DEVICE_ID_SYNAPTICS_DPAD 0x0013 ++ ++#define USB_VENDOR_ID_THRUSTMASTER 0x044f ++ ++#define USB_VENDOR_ID_TIVO 0x150a ++#define USB_DEVICE_ID_TIVO_SLIDE_BT 0x1200 ++#define USB_DEVICE_ID_TIVO_SLIDE 0x1201 ++ ++#define USB_VENDOR_ID_TOPSEED 0x0766 ++#define USB_DEVICE_ID_TOPSEED_CYBERLINK 0x0204 ++ ++#define USB_VENDOR_ID_TOPSEED2 0x1784 ++#define USB_DEVICE_ID_TOPSEED2_RF_COMBO 0x0004 ++#define USB_DEVICE_ID_TOPSEED2_PERIPAD_701 0x0016 ++ ++#define USB_VENDOR_ID_TOPMAX 0x0663 ++#define USB_DEVICE_ID_TOPMAX_COBRAPAD 0x0103 ++ ++#define USB_VENDOR_ID_TOUCH_INTL 0x1e5e ++#define USB_DEVICE_ID_TOUCH_INTL_MULTI_TOUCH 0x0313 ++ ++#define USB_VENDOR_ID_TOUCHPACK 0x1bfd ++#define USB_DEVICE_ID_TOUCHPACK_RTS 0x1688 ++ ++#define USB_VENDOR_ID_TPV 0x25aa ++#define USB_DEVICE_ID_TPV_OPTICAL_TOUCHSCREEN 0x8883 ++ ++#define USB_VENDOR_ID_TURBOX 0x062a ++#define USB_DEVICE_ID_TURBOX_KEYBOARD 0x0201 ++#define USB_DEVICE_ID_TURBOX_TOUCHSCREEN_MOSART 0x7100 ++ ++#define USB_VENDOR_ID_TWINHAN 0x6253 ++#define USB_DEVICE_ID_TWINHAN_IR_REMOTE 0x0100 ++ ++#define USB_VENDOR_ID_UCLOGIC 0x5543 ++#define USB_DEVICE_ID_UCLOGIC_TABLET_PF1209 0x0042 ++#define USB_DEVICE_ID_UCLOGIC_TABLET_KNA5 0x6001 ++#define USB_DEVICE_ID_UCLOGIC_TABLET_TWA60 0x0064 ++#define USB_DEVICE_ID_UCLOGIC_TABLET_WP4030U 0x0003 ++#define USB_DEVICE_ID_UCLOGIC_TABLET_WP5540U 0x0004 ++#define USB_DEVICE_ID_UCLOGIC_TABLET_WP8060U 0x0005 ++#define USB_DEVICE_ID_UCLOGIC_TABLET_WP1062 0x0064 ++#define USB_DEVICE_ID_UCLOGIC_WIRELESS_TABLET_TWHL850 0x0522 ++#define USB_DEVICE_ID_UCLOGIC_TABLET_TWHA60 0x0781 ++ ++#define USB_VENDOR_ID_UNITEC 0x227d ++#define USB_DEVICE_ID_UNITEC_USB_TOUCH_0709 0x0709 ++#define USB_DEVICE_ID_UNITEC_USB_TOUCH_0A19 0x0a19 ++ ++#define USB_VENDOR_ID_VERNIER 0x08f7 ++#define USB_DEVICE_ID_VERNIER_LABPRO 0x0001 ++#define USB_DEVICE_ID_VERNIER_GOTEMP 0x0002 ++#define USB_DEVICE_ID_VERNIER_SKIP 0x0003 ++#define USB_DEVICE_ID_VERNIER_CYCLOPS 0x0004 ++#define USB_DEVICE_ID_VERNIER_LCSPEC 0x0006 ++ ++#define USB_VENDOR_ID_WACOM 0x056a ++#define USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH 0x81 ++#define USB_DEVICE_ID_WACOM_INTUOS4_BLUETOOTH 0x00BD ++ ++#define USB_VENDOR_ID_WALTOP 0x172f ++#define USB_DEVICE_ID_WALTOP_SLIM_TABLET_5_8_INCH 0x0032 ++#define USB_DEVICE_ID_WALTOP_SLIM_TABLET_12_1_INCH 0x0034 ++#define USB_DEVICE_ID_WALTOP_Q_PAD 0x0037 ++#define USB_DEVICE_ID_WALTOP_PID_0038 0x0038 ++#define USB_DEVICE_ID_WALTOP_MEDIA_TABLET_10_6_INCH 0x0501 ++#define USB_DEVICE_ID_WALTOP_MEDIA_TABLET_14_1_INCH 0x0500 ++#define USB_DEVICE_ID_WALTOP_SIRIUS_BATTERY_FREE_TABLET 0x0502 ++ ++#define USB_VENDOR_ID_WISEGROUP 0x0925 ++#define USB_DEVICE_ID_SMARTJOY_PLUS 0x0005 ++#define USB_DEVICE_ID_1_PHIDGETSERVO_20 0x8101 ++#define USB_DEVICE_ID_4_PHIDGETSERVO_20 0x8104 ++#define USB_DEVICE_ID_8_8_4_IF_KIT 0x8201 ++#define USB_DEVICE_ID_SUPER_JOY_BOX_3 0x8888 ++#define USB_DEVICE_ID_QUAD_USB_JOYPAD 0x8800 ++#define USB_DEVICE_ID_DUAL_USB_JOYPAD 0x8866 ++ ++#define USB_VENDOR_ID_WISEGROUP_LTD 0x6666 ++#define USB_VENDOR_ID_WISEGROUP_LTD2 0x6677 ++#define USB_DEVICE_ID_SMARTJOY_DUAL_PLUS 0x8802 ++#define USB_DEVICE_ID_SUPER_JOY_BOX_3_PRO 0x8801 ++#define USB_DEVICE_ID_SUPER_DUAL_BOX_PRO 0x8802 ++#define USB_DEVICE_ID_SUPER_JOY_BOX_5_PRO 0x8804 ++ ++#define USB_VENDOR_ID_X_TENSIONS 0x1ae7 ++#define USB_DEVICE_ID_SPEEDLINK_VAD_CEZANNE 0x9001 ++ ++#define USB_VENDOR_ID_XAT 0x2505 ++#define USB_DEVICE_ID_XAT_CSR 0x0220 ++ ++#define USB_VENDOR_ID_XIROKU 0x1477 ++#define USB_DEVICE_ID_XIROKU_SPX 0x1006 ++#define USB_DEVICE_ID_XIROKU_MPX 0x1007 ++#define USB_DEVICE_ID_XIROKU_CSR 0x100e ++#define USB_DEVICE_ID_XIROKU_SPX1 0x1021 ++#define USB_DEVICE_ID_XIROKU_CSR1 0x1022 ++#define USB_DEVICE_ID_XIROKU_MPX1 0x1023 ++#define USB_DEVICE_ID_XIROKU_SPX2 0x1024 ++#define USB_DEVICE_ID_XIROKU_CSR2 0x1025 ++#define USB_DEVICE_ID_XIROKU_MPX2 0x1026 ++ ++#define USB_VENDOR_ID_YEALINK 0x6993 ++#define USB_DEVICE_ID_YEALINK_P1K_P4K_B2K 0xb001 ++ ++#define USB_VENDOR_ID_ZEROPLUS 0x0c12 ++ ++#define USB_VENDOR_ID_ZYDACRON 0x13EC ++#define USB_DEVICE_ID_ZYDACRON_REMOTE_CONTROL 0x0006 ++ ++#define USB_VENDOR_ID_ZYTRONIC 0x14c8 ++#define USB_DEVICE_ID_ZYTRONIC_ZXY100 0x0005 ++ ++#define USB_VENDOR_ID_PRIMAX 0x0461 ++#define USB_DEVICE_ID_PRIMAX_KEYBOARD 0x4e05 ++ ++#endif diff --cc compat/compat/kfifo.c index 000000000000,000000000000..96e1bdfd0e92 new file mode 100644 --- /dev/null +++ b/compat/compat/kfifo.c @@@ -1,0 -1,0 +1,608 @@@ ++/* ++ * A generic kernel FIFO implementation ++ * ++ * Copyright (C) 2009/2010 Stefani Seibold ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* ++ * internal helper to calculate the unused elements in a fifo ++ */ ++static inline unsigned int kfifo_unused(struct __kfifo *fifo) ++{ ++ return (fifo->mask + 1) - (fifo->in - fifo->out); ++} ++ ++int __kfifo_alloc(struct __kfifo *fifo, unsigned int size, ++ size_t esize, gfp_t gfp_mask) ++{ ++ /* ++ * round down to the next power of 2, since our 'let the indices ++ * wrap' technique works only in this case. ++ */ ++ if (!is_power_of_2(size)) ++ size = rounddown_pow_of_two(size); ++ ++ fifo->in = 0; ++ fifo->out = 0; ++ fifo->esize = esize; ++ ++ if (size < 2) { ++ fifo->data = NULL; ++ fifo->mask = 0; ++ return -EINVAL; ++ } ++ ++ fifo->data = kmalloc(size * esize, gfp_mask); ++ ++ if (!fifo->data) { ++ fifo->mask = 0; ++ return -ENOMEM; ++ } ++ fifo->mask = size - 1; ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(__kfifo_alloc); ++ ++void __kfifo_free(struct __kfifo *fifo) ++{ ++ kfree(fifo->data); ++ fifo->in = 0; ++ fifo->out = 0; ++ fifo->esize = 0; ++ fifo->data = NULL; ++ fifo->mask = 0; ++} ++EXPORT_SYMBOL_GPL(__kfifo_free); ++ ++int __kfifo_init(struct __kfifo *fifo, void *buffer, ++ unsigned int size, size_t esize) ++{ ++ size /= esize; ++ ++ if (!is_power_of_2(size)) ++ size = rounddown_pow_of_two(size); ++ ++ fifo->in = 0; ++ fifo->out = 0; ++ fifo->esize = esize; ++ fifo->data = buffer; ++ ++ if (size < 2) { ++ fifo->mask = 0; ++ return -EINVAL; ++ } ++ fifo->mask = size - 1; ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(__kfifo_init); ++ ++static void kfifo_copy_in(struct __kfifo *fifo, const void *src, ++ unsigned int len, unsigned int off) ++{ ++ unsigned int size = fifo->mask + 1; ++ unsigned int esize = fifo->esize; ++ unsigned int l; ++ ++ off &= fifo->mask; ++ if (esize != 1) { ++ off *= esize; ++ size *= esize; ++ len *= esize; ++ } ++ l = min(len, size - off); ++ ++ memcpy(fifo->data + off, src, l); ++ memcpy(fifo->data, src + l, len - l); ++ /* ++ * make sure that the data in the fifo is up to date before ++ * incrementing the fifo->in index counter ++ */ ++ smp_wmb(); ++} ++ ++unsigned int __kfifo_in(struct __kfifo *fifo, ++ const void *buf, unsigned int len) ++{ ++ unsigned int l; ++ ++ l = kfifo_unused(fifo); ++ if (len > l) ++ len = l; ++ ++ kfifo_copy_in(fifo, buf, len, fifo->in); ++ fifo->in += len; ++ return len; ++} ++EXPORT_SYMBOL_GPL(__kfifo_in); ++ ++static void kfifo_copy_out(struct __kfifo *fifo, void *dst, ++ unsigned int len, unsigned int off) ++{ ++ unsigned int size = fifo->mask + 1; ++ unsigned int esize = fifo->esize; ++ unsigned int l; ++ ++ off &= fifo->mask; ++ if (esize != 1) { ++ off *= esize; ++ size *= esize; ++ len *= esize; ++ } ++ l = min(len, size - off); ++ ++ memcpy(dst, fifo->data + off, l); ++ memcpy(dst + l, fifo->data, len - l); ++ /* ++ * make sure that the data is copied before ++ * incrementing the fifo->out index counter ++ */ ++ smp_wmb(); ++} ++ ++unsigned int __kfifo_out_peek(struct __kfifo *fifo, ++ void *buf, unsigned int len) ++{ ++ unsigned int l; ++ ++ l = fifo->in - fifo->out; ++ if (len > l) ++ len = l; ++ ++ kfifo_copy_out(fifo, buf, len, fifo->out); ++ return len; ++} ++EXPORT_SYMBOL_GPL(__kfifo_out_peek); ++ ++unsigned int __kfifo_out(struct __kfifo *fifo, ++ void *buf, unsigned int len) ++{ ++ len = __kfifo_out_peek(fifo, buf, len); ++ fifo->out += len; ++ return len; ++} ++EXPORT_SYMBOL_GPL(__kfifo_out); ++ ++static unsigned long kfifo_copy_from_user(struct __kfifo *fifo, ++ const void __user *from, unsigned int len, unsigned int off, ++ unsigned int *copied) ++{ ++ unsigned int size = fifo->mask + 1; ++ unsigned int esize = fifo->esize; ++ unsigned int l; ++ unsigned long ret; ++ ++ off &= fifo->mask; ++ if (esize != 1) { ++ off *= esize; ++ size *= esize; ++ len *= esize; ++ } ++ l = min(len, size - off); ++ ++ ret = copy_from_user(fifo->data + off, from, l); ++ if (unlikely(ret)) ++ ret = DIV_ROUND_UP(ret + len - l, esize); ++ else { ++ ret = copy_from_user(fifo->data, from + l, len - l); ++ if (unlikely(ret)) ++ ret = DIV_ROUND_UP(ret, esize); ++ } ++ /* ++ * make sure that the data in the fifo is up to date before ++ * incrementing the fifo->in index counter ++ */ ++ smp_wmb(); ++ *copied = len - ret; ++ /* return the number of elements which are not copied */ ++ return ret; ++} ++ ++int __kfifo_from_user(struct __kfifo *fifo, const void __user *from, ++ unsigned long len, unsigned int *copied) ++{ ++ unsigned int l; ++ unsigned long ret; ++ unsigned int esize = fifo->esize; ++ int err; ++ ++ if (esize != 1) ++ len /= esize; ++ ++ l = kfifo_unused(fifo); ++ if (len > l) ++ len = l; ++ ++ ret = kfifo_copy_from_user(fifo, from, len, fifo->in, copied); ++ if (unlikely(ret)) { ++ len -= ret; ++ err = -EFAULT; ++ } else ++ err = 0; ++ fifo->in += len; ++ return err; ++} ++EXPORT_SYMBOL_GPL(__kfifo_from_user); ++ ++static unsigned long kfifo_copy_to_user(struct __kfifo *fifo, void __user *to, ++ unsigned int len, unsigned int off, unsigned int *copied) ++{ ++ unsigned int l; ++ unsigned long ret; ++ unsigned int size = fifo->mask + 1; ++ unsigned int esize = fifo->esize; ++ ++ off &= fifo->mask; ++ if (esize != 1) { ++ off *= esize; ++ size *= esize; ++ len *= esize; ++ } ++ l = min(len, size - off); ++ ++ ret = copy_to_user(to, fifo->data + off, l); ++ if (unlikely(ret)) ++ ret = DIV_ROUND_UP(ret + len - l, esize); ++ else { ++ ret = copy_to_user(to + l, fifo->data, len - l); ++ if (unlikely(ret)) ++ ret = DIV_ROUND_UP(ret, esize); ++ } ++ /* ++ * make sure that the data is copied before ++ * incrementing the fifo->out index counter ++ */ ++ smp_wmb(); ++ *copied = len - ret; ++ /* return the number of elements which are not copied */ ++ return ret; ++} ++ ++int __kfifo_to_user(struct __kfifo *fifo, void __user *to, ++ unsigned long len, unsigned int *copied) ++{ ++ unsigned int l; ++ unsigned long ret; ++ unsigned int esize = fifo->esize; ++ int err; ++ ++ if (esize != 1) ++ len /= esize; ++ ++ l = fifo->in - fifo->out; ++ if (len > l) ++ len = l; ++ ret = kfifo_copy_to_user(fifo, to, len, fifo->out, copied); ++ if (unlikely(ret)) { ++ len -= ret; ++ err = -EFAULT; ++ } else ++ err = 0; ++ fifo->out += len; ++ return err; ++} ++EXPORT_SYMBOL_GPL(__kfifo_to_user); ++ ++static int setup_sgl_buf(struct scatterlist *sgl, void *buf, ++ int nents, unsigned int len) ++{ ++ int n; ++ unsigned int l; ++ unsigned int off; ++ struct page *page; ++ ++ if (!nents) ++ return 0; ++ ++ if (!len) ++ return 0; ++ ++ n = 0; ++ page = virt_to_page(buf); ++ off = offset_in_page(buf); ++ l = 0; ++ ++ while (len >= l + PAGE_SIZE - off) { ++ struct page *npage; ++ ++ l += PAGE_SIZE; ++ buf += PAGE_SIZE; ++ npage = virt_to_page(buf); ++ if (page_to_phys(page) != page_to_phys(npage) - l) { ++ sg_set_page(sgl, page, l - off, off); ++ sgl = sg_next(sgl); ++ if (++n == nents || sgl == NULL) ++ return n; ++ page = npage; ++ len -= l - off; ++ l = off = 0; ++ } ++ } ++ sg_set_page(sgl, page, len, off); ++ return n + 1; ++} ++ ++static unsigned int setup_sgl(struct __kfifo *fifo, struct scatterlist *sgl, ++ int nents, unsigned int len, unsigned int off) ++{ ++ unsigned int size = fifo->mask + 1; ++ unsigned int esize = fifo->esize; ++ unsigned int l; ++ unsigned int n; ++ ++ off &= fifo->mask; ++ if (esize != 1) { ++ off *= esize; ++ size *= esize; ++ len *= esize; ++ } ++ l = min(len, size - off); ++ ++ n = setup_sgl_buf(sgl, fifo->data + off, nents, l); ++ n += setup_sgl_buf(sgl + n, fifo->data, nents - n, len - l); ++ ++ return n; ++} ++ ++unsigned int __kfifo_dma_in_prepare(struct __kfifo *fifo, ++ struct scatterlist *sgl, int nents, unsigned int len) ++{ ++ unsigned int l; ++ ++ l = kfifo_unused(fifo); ++ if (len > l) ++ len = l; ++ ++ return setup_sgl(fifo, sgl, nents, len, fifo->in); ++} ++EXPORT_SYMBOL_GPL(__kfifo_dma_in_prepare); ++ ++unsigned int __kfifo_dma_out_prepare(struct __kfifo *fifo, ++ struct scatterlist *sgl, int nents, unsigned int len) ++{ ++ unsigned int l; ++ ++ l = fifo->in - fifo->out; ++ if (len > l) ++ len = l; ++ ++ return setup_sgl(fifo, sgl, nents, len, fifo->out); ++} ++EXPORT_SYMBOL_GPL(__kfifo_dma_out_prepare); ++ ++unsigned int __kfifo_max_r(unsigned int len, size_t recsize) ++{ ++ unsigned int max = (1 << (recsize << 3)) - 1; ++ ++ if (len > max) ++ return max; ++ return len; ++} ++ ++#define __KFIFO_PEEK(data, out, mask) \ ++ ((data)[(out) & (mask)]) ++/* ++ * __kfifo_peek_n internal helper function for determinate the length of ++ * the next record in the fifo ++ */ ++static unsigned int __kfifo_peek_n(struct __kfifo *fifo, size_t recsize) ++{ ++ unsigned int l; ++ unsigned int mask = fifo->mask; ++ unsigned char *data = fifo->data; ++ ++ l = __KFIFO_PEEK(data, fifo->out, mask); ++ ++ if (--recsize) ++ l |= __KFIFO_PEEK(data, fifo->out + 1, mask) << 8; ++ ++ return l; ++} ++ ++#define __KFIFO_POKE(data, in, mask, val) \ ++ ( \ ++ (data)[(in) & (mask)] = (unsigned char)(val) \ ++ ) ++ ++/* ++ * __kfifo_poke_n internal helper function for storeing the length of ++ * the record into the fifo ++ */ ++static void __kfifo_poke_n(struct __kfifo *fifo, unsigned int n, size_t recsize) ++{ ++ unsigned int mask = fifo->mask; ++ unsigned char *data = fifo->data; ++ ++ __KFIFO_POKE(data, fifo->in, mask, n); ++ ++ if (recsize > 1) ++ __KFIFO_POKE(data, fifo->in + 1, mask, n >> 8); ++} ++ ++unsigned int __kfifo_len_r(struct __kfifo *fifo, size_t recsize) ++{ ++ return __kfifo_peek_n(fifo, recsize); ++} ++EXPORT_SYMBOL_GPL(__kfifo_len_r); ++ ++unsigned int __kfifo_in_r(struct __kfifo *fifo, const void *buf, ++ unsigned int len, size_t recsize) ++{ ++ if (len + recsize > kfifo_unused(fifo)) ++ return 0; ++ ++ __kfifo_poke_n(fifo, len, recsize); ++ ++ kfifo_copy_in(fifo, buf, len, fifo->in + recsize); ++ fifo->in += len + recsize; ++ return len; ++} ++EXPORT_SYMBOL_GPL(__kfifo_in_r); ++ ++static unsigned int kfifo_out_copy_r(struct __kfifo *fifo, ++ void *buf, unsigned int len, size_t recsize, unsigned int *n) ++{ ++ *n = __kfifo_peek_n(fifo, recsize); ++ ++ if (len > *n) ++ len = *n; ++ ++ kfifo_copy_out(fifo, buf, len, fifo->out + recsize); ++ return len; ++} ++ ++unsigned int __kfifo_out_peek_r(struct __kfifo *fifo, void *buf, ++ unsigned int len, size_t recsize) ++{ ++ unsigned int n; ++ ++ if (fifo->in == fifo->out) ++ return 0; ++ ++ return kfifo_out_copy_r(fifo, buf, len, recsize, &n); ++} ++EXPORT_SYMBOL_GPL(__kfifo_out_peek_r); ++ ++unsigned int __kfifo_out_r(struct __kfifo *fifo, void *buf, ++ unsigned int len, size_t recsize) ++{ ++ unsigned int n; ++ ++ if (fifo->in == fifo->out) ++ return 0; ++ ++ len = kfifo_out_copy_r(fifo, buf, len, recsize, &n); ++ fifo->out += n + recsize; ++ return len; ++} ++EXPORT_SYMBOL_GPL(__kfifo_out_r); ++ ++void __kfifo_skip_r(struct __kfifo *fifo, size_t recsize) ++{ ++ unsigned int n; ++ ++ n = __kfifo_peek_n(fifo, recsize); ++ fifo->out += n + recsize; ++} ++EXPORT_SYMBOL_GPL(__kfifo_skip_r); ++ ++int __kfifo_from_user_r(struct __kfifo *fifo, const void __user *from, ++ unsigned long len, unsigned int *copied, size_t recsize) ++{ ++ unsigned long ret; ++ ++ len = __kfifo_max_r(len, recsize); ++ ++ if (len + recsize > kfifo_unused(fifo)) { ++ *copied = 0; ++ return 0; ++ } ++ ++ __kfifo_poke_n(fifo, len, recsize); ++ ++ ret = kfifo_copy_from_user(fifo, from, len, fifo->in + recsize, copied); ++ if (unlikely(ret)) { ++ *copied = 0; ++ return -EFAULT; ++ } ++ fifo->in += len + recsize; ++ return 0; ++} ++EXPORT_SYMBOL_GPL(__kfifo_from_user_r); ++ ++int __kfifo_to_user_r(struct __kfifo *fifo, void __user *to, ++ unsigned long len, unsigned int *copied, size_t recsize) ++{ ++ unsigned long ret; ++ unsigned int n; ++ ++ if (fifo->in == fifo->out) { ++ *copied = 0; ++ return 0; ++ } ++ ++ n = __kfifo_peek_n(fifo, recsize); ++ if (len > n) ++ len = n; ++ ++ ret = kfifo_copy_to_user(fifo, to, len, fifo->out + recsize, copied); ++ if (unlikely(ret)) { ++ *copied = 0; ++ return -EFAULT; ++ } ++ fifo->out += n + recsize; ++ return 0; ++} ++EXPORT_SYMBOL_GPL(__kfifo_to_user_r); ++ ++unsigned int __kfifo_dma_in_prepare_r(struct __kfifo *fifo, ++ struct scatterlist *sgl, int nents, unsigned int len, size_t recsize) ++{ ++ if (!nents) ++ BUG(); ++ ++ len = __kfifo_max_r(len, recsize); ++ ++ if (len + recsize > kfifo_unused(fifo)) ++ return 0; ++ ++ return setup_sgl(fifo, sgl, nents, len, fifo->in + recsize); ++} ++EXPORT_SYMBOL_GPL(__kfifo_dma_in_prepare_r); ++ ++void __kfifo_dma_in_finish_r(struct __kfifo *fifo, ++ unsigned int len, size_t recsize) ++{ ++ len = __kfifo_max_r(len, recsize); ++ __kfifo_poke_n(fifo, len, recsize); ++ fifo->in += len + recsize; ++} ++EXPORT_SYMBOL_GPL(__kfifo_dma_in_finish_r); ++ ++unsigned int __kfifo_dma_out_prepare_r(struct __kfifo *fifo, ++ struct scatterlist *sgl, int nents, unsigned int len, size_t recsize) ++{ ++ if (!nents) ++ BUG(); ++ ++ len = __kfifo_max_r(len, recsize); ++ ++ if (len + recsize > fifo->in - fifo->out) ++ return 0; ++ ++ return setup_sgl(fifo, sgl, nents, len, fifo->out + recsize); ++} ++EXPORT_SYMBOL_GPL(__kfifo_dma_out_prepare_r); ++ ++void __kfifo_dma_out_finish_r(struct __kfifo *fifo, size_t recsize) ++{ ++ unsigned int len; ++ ++ len = __kfifo_peek_n(fifo, recsize); ++ fifo->out += len + recsize; ++} ++EXPORT_SYMBOL_GPL(__kfifo_dma_out_finish_r); diff --cc compat/compat/kstrtox.c index 000000000000,000000000000..fdbc56eb3f04 new file mode 100644 --- /dev/null +++ b/compat/compat/kstrtox.c @@@ -1,0 -1,0 +1,236 @@@ ++/* ++ * Convert integer string representation to an integer. ++ * If an integer doesn't fit into specified type, -E is returned. ++ * ++ * Integer starts with optional sign. ++ * kstrtou*() functions do not accept sign "-". ++ * ++ * Radix 0 means autodetection: leading "0x" implies radix 16, ++ * leading "0" implies radix 8, otherwise radix is 10. ++ * Autodetection hints work after optional sign, but not before. ++ * ++ * If -E is returned, result is not touched. ++ */ ++#include ++/* ++ * kstrto* was included in kernel 2.6.38.4 and causes conflicts with the ++ * version included in compat-drivers. We use strict_strtol to check if ++ * kstrto* is already available. ++ */ ++#ifndef strict_strtoll ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static inline char _tolower(const char c) ++{ ++ return c | 0x20; ++} ++ ++static int _kstrtoull(const char *s, unsigned int base, unsigned long long *res) ++{ ++ unsigned long long acc; ++ int ok; ++ ++ if (base == 0) { ++ if (s[0] == '0') { ++ if (_tolower(s[1]) == 'x' && isxdigit(s[2])) ++ base = 16; ++ else ++ base = 8; ++ } else ++ base = 10; ++ } ++ if (base == 16 && s[0] == '0' && _tolower(s[1]) == 'x') ++ s += 2; ++ ++ acc = 0; ++ ok = 0; ++ while (*s) { ++ unsigned int val; ++ ++ if ('0' <= *s && *s <= '9') ++ val = *s - '0'; ++ else if ('a' <= _tolower(*s) && _tolower(*s) <= 'f') ++ val = _tolower(*s) - 'a' + 10; ++ else if (*s == '\n') { ++ if (*(s + 1) == '\0') ++ break; ++ else ++ return -EINVAL; ++ } else ++ return -EINVAL; ++ ++ if (val >= base) ++ return -EINVAL; ++ if (acc > div_u64(ULLONG_MAX - val, base)) ++ return -ERANGE; ++ acc = acc * base + val; ++ ok = 1; ++ ++ s++; ++ } ++ if (!ok) ++ return -EINVAL; ++ *res = acc; ++ return 0; ++} ++ ++int kstrtoull(const char *s, unsigned int base, unsigned long long *res) ++{ ++ if (s[0] == '+') ++ s++; ++ return _kstrtoull(s, base, res); ++} ++EXPORT_SYMBOL_GPL(kstrtoull); ++ ++int kstrtoll(const char *s, unsigned int base, long long *res) ++{ ++ unsigned long long tmp; ++ int rv; ++ ++ if (s[0] == '-') { ++ rv = _kstrtoull(s + 1, base, &tmp); ++ if (rv < 0) ++ return rv; ++ if ((long long)(-tmp) >= 0) ++ return -ERANGE; ++ *res = -tmp; ++ } else { ++ rv = kstrtoull(s, base, &tmp); ++ if (rv < 0) ++ return rv; ++ if ((long long)tmp < 0) ++ return -ERANGE; ++ *res = tmp; ++ } ++ return 0; ++} ++EXPORT_SYMBOL_GPL(kstrtoll); ++ ++/* Internal, do not use. */ ++int _kstrtoul(const char *s, unsigned int base, unsigned long *res) ++{ ++ unsigned long long tmp; ++ int rv; ++ ++ rv = kstrtoull(s, base, &tmp); ++ if (rv < 0) ++ return rv; ++ if (tmp != (unsigned long long)(unsigned long)tmp) ++ return -ERANGE; ++ *res = tmp; ++ return 0; ++} ++EXPORT_SYMBOL_GPL(_kstrtoul); ++ ++/* Internal, do not use. */ ++int _kstrtol(const char *s, unsigned int base, long *res) ++{ ++ long long tmp; ++ int rv; ++ ++ rv = kstrtoll(s, base, &tmp); ++ if (rv < 0) ++ return rv; ++ if (tmp != (long long)(long)tmp) ++ return -ERANGE; ++ *res = tmp; ++ return 0; ++} ++EXPORT_SYMBOL_GPL(_kstrtol); ++ ++int kstrtouint(const char *s, unsigned int base, unsigned int *res) ++{ ++ unsigned long long tmp; ++ int rv; ++ ++ rv = kstrtoull(s, base, &tmp); ++ if (rv < 0) ++ return rv; ++ if (tmp != (unsigned long long)(unsigned int)tmp) ++ return -ERANGE; ++ *res = tmp; ++ return 0; ++} ++EXPORT_SYMBOL_GPL(kstrtouint); ++ ++int kstrtoint(const char *s, unsigned int base, int *res) ++{ ++ long long tmp; ++ int rv; ++ ++ rv = kstrtoll(s, base, &tmp); ++ if (rv < 0) ++ return rv; ++ if (tmp != (long long)(int)tmp) ++ return -ERANGE; ++ *res = tmp; ++ return 0; ++} ++EXPORT_SYMBOL_GPL(kstrtoint); ++ ++int kstrtou16(const char *s, unsigned int base, u16 *res) ++{ ++ unsigned long long tmp; ++ int rv; ++ ++ rv = kstrtoull(s, base, &tmp); ++ if (rv < 0) ++ return rv; ++ if (tmp != (unsigned long long)(u16)tmp) ++ return -ERANGE; ++ *res = tmp; ++ return 0; ++} ++EXPORT_SYMBOL_GPL(kstrtou16); ++ ++int kstrtos16(const char *s, unsigned int base, s16 *res) ++{ ++ long long tmp; ++ int rv; ++ ++ rv = kstrtoll(s, base, &tmp); ++ if (rv < 0) ++ return rv; ++ if (tmp != (long long)(s16)tmp) ++ return -ERANGE; ++ *res = tmp; ++ return 0; ++} ++EXPORT_SYMBOL_GPL(kstrtos16); ++ ++int kstrtou8(const char *s, unsigned int base, u8 *res) ++{ ++ unsigned long long tmp; ++ int rv; ++ ++ rv = kstrtoull(s, base, &tmp); ++ if (rv < 0) ++ return rv; ++ if (tmp != (unsigned long long)(u8)tmp) ++ return -ERANGE; ++ *res = tmp; ++ return 0; ++} ++EXPORT_SYMBOL_GPL(kstrtou8); ++ ++int kstrtos8(const char *s, unsigned int base, s8 *res) ++{ ++ long long tmp; ++ int rv; ++ ++ rv = kstrtoll(s, base, &tmp); ++ if (rv < 0) ++ return rv; ++ if (tmp != (long long)(s8)tmp) ++ return -ERANGE; ++ *res = tmp; ++ return 0; ++} ++EXPORT_SYMBOL_GPL(kstrtos8); ++#endif /* #ifndef strict_strtol */ diff --cc compat/compat/main.c index 000000000000,000000000000..4e72ca5599a8 new file mode 100644 --- /dev/null +++ b/compat/compat/main.c @@@ -1,0 -1,0 +1,79 @@@ ++#include ++#include "compat-2.6.34.h" ++ ++MODULE_AUTHOR("Luis R. Rodriguez"); ++MODULE_DESCRIPTION("Kernel backport module"); ++MODULE_LICENSE("GPL"); ++ ++#ifndef COMPAT_BASE ++#error "You need a COMPAT_BASE" ++#endif ++ ++#ifndef COMPAT_BASE_TREE ++#error "You need a COMPAT_BASE_TREE" ++#endif ++ ++#ifndef COMPAT_BASE_TREE_VERSION ++#error "You need a COMPAT_BASE_TREE_VERSION" ++#endif ++ ++#ifndef COMPAT_VERSION ++#error "You need a COMPAT_VERSION" ++#endif ++ ++static char *compat_base = COMPAT_BASE; ++static char *compat_base_tree = COMPAT_BASE_TREE; ++static char *compat_base_tree_version = COMPAT_BASE_TREE_VERSION; ++static char *compat_version = COMPAT_VERSION; ++ ++module_param(compat_base, charp, 0400); ++MODULE_PARM_DESC(compat_base_tree, ++ "The upstream verion of compat.git used"); ++ ++module_param(compat_base_tree, charp, 0400); ++MODULE_PARM_DESC(compat_base_tree, ++ "The upstream tree used as base for this backport"); ++ ++module_param(compat_base_tree_version, charp, 0400); ++MODULE_PARM_DESC(compat_base_tree_version, ++ "The git-describe of the upstream base tree"); ++ ++module_param(compat_version, charp, 0400); ++MODULE_PARM_DESC(compat_version, ++ "Version of the kernel compat backport work"); ++ ++void backport_dependency_symbol(void) ++{ ++} ++EXPORT_SYMBOL_GPL(backport_dependency_symbol); ++ ++ ++static int __init backport_init(void) ++{ ++ backport_pm_qos_power_init(); ++ backport_system_workqueue_create(); ++ backport_init_mmc_pm_flags(); ++ ++ printk(KERN_INFO ++ COMPAT_PROJECT " backport release: " ++ COMPAT_VERSION ++ "\n"); ++ printk(KERN_INFO "Backport based on " ++ COMPAT_BASE_TREE " " COMPAT_BASE_TREE_VERSION ++ "\n"); ++ printk(KERN_INFO "compat.git: " ++ COMPAT_BASE_TREE "\n"); ++ ++ return 0; ++} ++module_init(backport_init); ++ ++static void __exit backport_exit(void) ++{ ++ backport_pm_qos_power_deinit(); ++ backport_system_workqueue_destroy(); ++ ++ return; ++} ++module_exit(backport_exit); ++ diff --cc compat/compat/pm_qos_params.c index 000000000000,000000000000..42785ce134be new file mode 100644 --- /dev/null +++ b/compat/compat/pm_qos_params.c @@@ -1,0 -1,0 +1,477 @@@ ++#include ++ ++/* This is the backport of pm-qos params for kernels <= 2.6.25 */ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25)) ++ ++/* ++ * This module exposes the interface to kernel space for specifying ++ * QoS dependencies. It provides infrastructure for registration of: ++ * ++ * Dependents on a QoS value : register requirements ++ * Watchers of QoS value : get notified when target QoS value changes ++ * ++ * This QoS design is best effort based. Dependents register their QoS needs. ++ * Watchers register to keep track of the current QoS needs of the system. ++ * ++ * There are 3 basic classes of QoS parameter: latency, timeout, throughput ++ * each have defined units: ++ * latency: usec ++ * timeout: usec <-- currently not used. ++ * throughput: kbs (kilo byte / sec) ++ * ++ * There are lists of pm_qos_objects each one wrapping requirements, notifiers ++ * ++ * User mode requirements on a QOS parameter register themselves to the ++ * subsystem by opening the device node /dev/... and writing there request to ++ * the node. As long as the process holds a file handle open to the node the ++ * client continues to be accounted for. Upon file release the usermode ++ * requirement is removed and a new qos target is computed. This way when the ++ * requirement that the application has is cleaned up when closes the file ++ * pointer or exits the pm_qos_object will get an opportunity to clean up. ++ * ++ * Mark Gross ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++/* ++ * locking rule: all changes to requirements or notifiers lists ++ * or pm_qos_object list and pm_qos_objects need to happen with pm_qos_lock ++ * held, taken with _irqsave. One lock to rule them all ++ */ ++struct requirement_list { ++ struct list_head list; ++ union { ++ s32 value; ++ s32 usec; ++ s32 kbps; ++ }; ++ char *name; ++}; ++ ++static s32 max_compare(s32 v1, s32 v2); ++static s32 min_compare(s32 v1, s32 v2); ++ ++struct pm_qos_object { ++ struct requirement_list requirements; ++ struct blocking_notifier_head *notifiers; ++ struct miscdevice pm_qos_power_miscdev; ++ char *name; ++ s32 default_value; ++ atomic_t target_value; ++ s32 (*comparitor)(s32, s32); ++}; ++ ++static struct pm_qos_object null_pm_qos; ++static BLOCKING_NOTIFIER_HEAD(cpu_dma_lat_notifier); ++static struct pm_qos_object cpu_dma_pm_qos = { ++ .requirements = {LIST_HEAD_INIT(cpu_dma_pm_qos.requirements.list)}, ++ .notifiers = &cpu_dma_lat_notifier, ++ .name = "cpu_dma_latency", ++ .default_value = 2000 * USEC_PER_SEC, ++ .target_value = ATOMIC_INIT(2000 * USEC_PER_SEC), ++ .comparitor = min_compare ++}; ++ ++static BLOCKING_NOTIFIER_HEAD(network_lat_notifier); ++static struct pm_qos_object network_lat_pm_qos = { ++ .requirements = {LIST_HEAD_INIT(network_lat_pm_qos.requirements.list)}, ++ .notifiers = &network_lat_notifier, ++ .name = "network_latency", ++ .default_value = 2000 * USEC_PER_SEC, ++ .target_value = ATOMIC_INIT(2000 * USEC_PER_SEC), ++ .comparitor = min_compare ++}; ++ ++ ++static BLOCKING_NOTIFIER_HEAD(network_throughput_notifier); ++static struct pm_qos_object network_throughput_pm_qos = { ++ .requirements = ++ {LIST_HEAD_INIT(network_throughput_pm_qos.requirements.list)}, ++ .notifiers = &network_throughput_notifier, ++ .name = "network_throughput", ++ .default_value = 0, ++ .target_value = ATOMIC_INIT(0), ++ .comparitor = max_compare ++}; ++ ++static BLOCKING_NOTIFIER_HEAD(system_bus_freq_notifier); ++static struct pm_qos_object system_bus_freq_pm_qos = { ++ .requirements = ++ {LIST_HEAD_INIT(system_bus_freq_pm_qos.requirements.list)}, ++ .notifiers = &system_bus_freq_notifier, ++ .name = "system_bus_freq", ++ .default_value = 0, ++ .target_value = ATOMIC_INIT(0), ++ .comparitor = max_compare ++}; ++ ++ ++static struct pm_qos_object *pm_qos_array[PM_QOS_NUM_CLASSES] = { ++ [PM_QOS_RESERVED] = &null_pm_qos, ++ [PM_QOS_CPU_DMA_LATENCY] = &cpu_dma_pm_qos, ++ [PM_QOS_NETWORK_LATENCY] = &network_lat_pm_qos, ++ [PM_QOS_NETWORK_THROUGHPUT] = &network_throughput_pm_qos, ++ [PM_QOS_SYSTEM_BUS_FREQ] = &system_bus_freq_pm_qos, ++}; ++ ++static DEFINE_SPINLOCK(pm_qos_lock); ++ ++static ssize_t pm_qos_power_write(struct file *filp, const char __user *buf, ++ size_t count, loff_t *f_pos); ++static int pm_qos_power_open(struct inode *inode, struct file *filp); ++static int pm_qos_power_release(struct inode *inode, struct file *filp); ++ ++static const struct file_operations pm_qos_power_fops = { ++ .write = pm_qos_power_write, ++ .open = pm_qos_power_open, ++ .release = pm_qos_power_release, ++}; ++ ++/* static helper functions */ ++static s32 max_compare(s32 v1, s32 v2) ++{ ++ return max(v1, v2); ++} ++ ++static s32 min_compare(s32 v1, s32 v2) ++{ ++ return min(v1, v2); ++} ++ ++ ++static void update_target(int target) ++{ ++ s32 extreme_value; ++ struct requirement_list *node; ++ unsigned long flags; ++ int call_notifier = 0; ++ ++ spin_lock_irqsave(&pm_qos_lock, flags); ++ extreme_value = pm_qos_array[target]->default_value; ++ list_for_each_entry(node, ++ &pm_qos_array[target]->requirements.list, list) { ++ extreme_value = pm_qos_array[target]->comparitor( ++ extreme_value, node->value); ++ } ++ if (atomic_read(&pm_qos_array[target]->target_value) != extreme_value) { ++ call_notifier = 1; ++ atomic_set(&pm_qos_array[target]->target_value, extreme_value); ++ pr_debug(KERN_ERR "new target for qos %d is %d\n", target, ++ atomic_read(&pm_qos_array[target]->target_value)); ++ } ++ spin_unlock_irqrestore(&pm_qos_lock, flags); ++ ++ if (call_notifier) ++ blocking_notifier_call_chain(pm_qos_array[target]->notifiers, ++ (unsigned long) extreme_value, NULL); ++} ++ ++static int register_pm_qos_misc(struct pm_qos_object *qos) ++{ ++ qos->pm_qos_power_miscdev.minor = MISC_DYNAMIC_MINOR; ++ qos->pm_qos_power_miscdev.name = qos->name; ++ qos->pm_qos_power_miscdev.fops = &pm_qos_power_fops; ++ ++ return misc_register(&qos->pm_qos_power_miscdev); ++} ++ ++static int find_pm_qos_object_by_minor(int minor) ++{ ++ int pm_qos_class; ++ ++ for (pm_qos_class = 0; ++ pm_qos_class < PM_QOS_NUM_CLASSES; pm_qos_class++) { ++ if (minor == ++ pm_qos_array[pm_qos_class]->pm_qos_power_miscdev.minor) ++ return pm_qos_class; ++ } ++ return -1; ++} ++ ++/** ++ * pm_qos_requirement - returns current system wide qos expectation ++ * @pm_qos_class: identification of which qos value is requested ++ * ++ * This function returns the current target value in an atomic manner. ++ */ ++int pm_qos_requirement(int pm_qos_class) ++{ ++ return atomic_read(&pm_qos_array[pm_qos_class]->target_value); ++} ++EXPORT_SYMBOL_GPL(pm_qos_requirement); ++ ++/** ++ * pm_qos_add_requirement - inserts new qos request into the list ++ * @pm_qos_class: identifies which list of qos request to us ++ * @name: identifies the request ++ * @value: defines the qos request ++ * ++ * This function inserts a new entry in the pm_qos_class list of requested qos ++ * performance characteristics. It recomputes the aggregate QoS expectations ++ * for the pm_qos_class of parameters. ++ */ ++int pm_qos_add_requirement(int pm_qos_class, char *name, s32 value) ++{ ++ struct requirement_list *dep; ++ unsigned long flags; ++ ++ dep = kzalloc(sizeof(struct requirement_list), GFP_KERNEL); ++ if (dep) { ++ if (value == PM_QOS_DEFAULT_VALUE) ++ dep->value = pm_qos_array[pm_qos_class]->default_value; ++ else ++ dep->value = value; ++ dep->name = kstrdup(name, GFP_KERNEL); ++ if (!dep->name) ++ goto cleanup; ++ ++ spin_lock_irqsave(&pm_qos_lock, flags); ++ list_add(&dep->list, ++ &pm_qos_array[pm_qos_class]->requirements.list); ++ spin_unlock_irqrestore(&pm_qos_lock, flags); ++ update_target(pm_qos_class); ++ ++ return 0; ++ } ++ ++cleanup: ++ kfree(dep); ++ return -ENOMEM; ++} ++EXPORT_SYMBOL_GPL(pm_qos_add_requirement); ++ ++/** ++ * pm_qos_update_requirement - modifies an existing qos request ++ * @pm_qos_class: identifies which list of qos request to us ++ * @name: identifies the request ++ * @value: defines the qos request ++ * ++ * Updates an existing qos requirement for the pm_qos_class of parameters along ++ * with updating the target pm_qos_class value. ++ * ++ * If the named request isn't in the list then no change is made. ++ */ ++int pm_qos_update_requirement(int pm_qos_class, char *name, s32 new_value) ++{ ++ unsigned long flags; ++ struct requirement_list *node; ++ int pending_update = 0; ++ ++ spin_lock_irqsave(&pm_qos_lock, flags); ++ list_for_each_entry(node, ++ &pm_qos_array[pm_qos_class]->requirements.list, list) { ++ if (strcmp(node->name, name) == 0) { ++ if (new_value == PM_QOS_DEFAULT_VALUE) ++ node->value = ++ pm_qos_array[pm_qos_class]->default_value; ++ else ++ node->value = new_value; ++ pending_update = 1; ++ break; ++ } ++ } ++ spin_unlock_irqrestore(&pm_qos_lock, flags); ++ if (pending_update) ++ update_target(pm_qos_class); ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(pm_qos_update_requirement); ++ ++/** ++ * pm_qos_remove_requirement - modifies an existing qos request ++ * @pm_qos_class: identifies which list of qos request to us ++ * @name: identifies the request ++ * ++ * Will remove named qos request from pm_qos_class list of parameters and ++ * recompute the current target value for the pm_qos_class. ++ */ ++void pm_qos_remove_requirement(int pm_qos_class, char *name) ++{ ++ unsigned long flags; ++ struct requirement_list *node; ++ int pending_update = 0; ++ ++ spin_lock_irqsave(&pm_qos_lock, flags); ++ list_for_each_entry(node, ++ &pm_qos_array[pm_qos_class]->requirements.list, list) { ++ if (strcmp(node->name, name) == 0) { ++ kfree(node->name); ++ list_del(&node->list); ++ kfree(node); ++ pending_update = 1; ++ break; ++ } ++ } ++ spin_unlock_irqrestore(&pm_qos_lock, flags); ++ if (pending_update) ++ update_target(pm_qos_class); ++} ++EXPORT_SYMBOL_GPL(pm_qos_remove_requirement); ++ ++/** ++ * pm_qos_add_notifier - sets notification entry for changes to target value ++ * @pm_qos_class: identifies which qos target changes should be notified. ++ * @notifier: notifier block managed by caller. ++ * ++ * will register the notifier into a notification chain that gets called ++ * upon changes to the pm_qos_class target value. ++ */ ++int pm_qos_add_notifier(int pm_qos_class, struct notifier_block *notifier) ++{ ++ int retval; ++ ++ retval = blocking_notifier_chain_register( ++ pm_qos_array[pm_qos_class]->notifiers, notifier); ++ ++ return retval; ++} ++EXPORT_SYMBOL_GPL(pm_qos_add_notifier); ++ ++/** ++ * pm_qos_remove_notifier - deletes notification entry from chain. ++ * @pm_qos_class: identifies which qos target changes are notified. ++ * @notifier: notifier block to be removed. ++ * ++ * will remove the notifier from the notification chain that gets called ++ * upon changes to the pm_qos_class target value. ++ */ ++int pm_qos_remove_notifier(int pm_qos_class, struct notifier_block *notifier) ++{ ++ int retval; ++ ++ retval = blocking_notifier_chain_unregister( ++ pm_qos_array[pm_qos_class]->notifiers, notifier); ++ ++ return retval; ++} ++EXPORT_SYMBOL_GPL(pm_qos_remove_notifier); ++ ++#define PID_NAME_LEN 32 ++ ++static int pm_qos_power_open(struct inode *inode, struct file *filp) ++{ ++ int ret; ++ long pm_qos_class; ++ char name[PID_NAME_LEN]; ++ ++ pm_qos_class = find_pm_qos_object_by_minor(iminor(inode)); ++ if (pm_qos_class >= 0) { ++ filp->private_data = (void *)pm_qos_class; ++ snprintf(name, PID_NAME_LEN, "process_%d", current->pid); ++ ret = pm_qos_add_requirement(pm_qos_class, name, ++ PM_QOS_DEFAULT_VALUE); ++ if (ret >= 0) ++ return 0; ++ } ++ return -EPERM; ++} ++ ++static int pm_qos_power_release(struct inode *inode, struct file *filp) ++{ ++ int pm_qos_class; ++ char name[PID_NAME_LEN]; ++ ++ pm_qos_class = (long)filp->private_data; ++ snprintf(name, PID_NAME_LEN, "process_%d", current->pid); ++ pm_qos_remove_requirement(pm_qos_class, name); ++ ++ return 0; ++} ++ ++static ssize_t pm_qos_power_write(struct file *filp, const char __user *buf, ++ size_t count, loff_t *f_pos) ++{ ++ s32 value; ++ int pm_qos_class; ++ char name[PID_NAME_LEN]; ++ ++ pm_qos_class = (long)filp->private_data; ++ if (count != sizeof(s32)) ++ return -EINVAL; ++ if (copy_from_user(&value, buf, sizeof(s32))) ++ return -EFAULT; ++ snprintf(name, PID_NAME_LEN, "process_%d", current->pid); ++ pm_qos_update_requirement(pm_qos_class, name, value); ++ ++ return sizeof(s32); ++} ++ ++ ++/* ++ * This initializes pm-qos for older kernels. ++ */ ++int backport_pm_qos_power_init(void) ++{ ++ int ret = 0; ++ ++ ret = register_pm_qos_misc(&cpu_dma_pm_qos); ++ if (ret < 0) { ++ printk(KERN_ERR "pm_qos_param: cpu_dma_latency setup failed\n"); ++ return ret; ++ } ++ ret = register_pm_qos_misc(&network_lat_pm_qos); ++ if (ret < 0) { ++ printk(KERN_ERR "pm_qos_param: network_latency setup failed\n"); ++ return ret; ++ } ++ ret = register_pm_qos_misc(&network_throughput_pm_qos); ++ if (ret < 0) { ++ printk(KERN_ERR ++ "pm_qos_param: network_throughput setup failed\n"); ++ return ret; ++ } ++ ret = register_pm_qos_misc(&system_bus_freq_pm_qos); ++ if (ret < 0) ++ printk(KERN_ERR ++ "pm_qos_param: system_bus_freq setup failed\n"); ++ ++ return ret; ++} ++ ++int backport_pm_qos_power_deinit(void) ++{ ++ int ret = 0; ++ ++ ret = misc_deregister(&cpu_dma_pm_qos.pm_qos_power_miscdev); ++ if (ret < 0) { ++ printk(KERN_ERR "pm_qos_param: cpu_dma_latency deinit failed\n"); ++ return ret; ++ } ++ ++ ret = misc_deregister(&network_lat_pm_qos.pm_qos_power_miscdev); ++ if (ret < 0) { ++ printk(KERN_ERR "pm_qos_param: network_latency deinit failed\n"); ++ return ret; ++ } ++ ++ ret = misc_deregister(&network_throughput_pm_qos.pm_qos_power_miscdev); ++ if (ret < 0) { ++ printk(KERN_ERR ++ "pm_qos_param: network_throughput deinit failed\n"); ++ return ret; ++ } ++ ++ ret = misc_deregister(&system_bus_freq_pm_qos.pm_qos_power_miscdev); ++ if (ret < 0) { ++ printk(KERN_ERR ++ "pm_qos_param: system_bus_freq deinit failed\n"); ++ return ret; ++ } ++ ++ return ret; ++} ++#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25) */ diff --cc compat/compat/sch_codel.c index 000000000000,000000000000..5ad66fbcbc5c new file mode 100644 --- /dev/null +++ b/compat/compat/sch_codel.c @@@ -1,0 -1,0 +1,306 @@@ ++/* ++ * Codel - The Controlled-Delay Active Queue Management algorithm ++ * ++ * Copyright (C) 2011-2012 Kathleen Nichols ++ * Copyright (C) 2011-2012 Van Jacobson ++ * ++ * Implemented on linux by : ++ * Copyright (C) 2012 Michael D. Taht ++ * Copyright (C) 2012 Eric Dumazet ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions, and the following disclaimer, ++ * without modification. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * 3. The names of the authors may not be used to endorse or promote products ++ * derived from this software without specific prior written permission. ++ * ++ * Alternatively, provided that this notice is retained in full, this ++ * software may be distributed under the terms of the GNU General ++ * Public License ("GPL") version 2, in which case the provisions of the ++ * GPL apply INSTEAD OF those given above. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH ++ * DAMAGE. ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++ ++#define DEFAULT_CODEL_LIMIT 1000 ++ ++struct codel_sched_data { ++ struct codel_params params; ++ struct codel_vars vars; ++ struct codel_stats stats; ++ u32 drop_overlimit; ++#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,39)) ++ u32 limit; ++#endif ++}; ++ ++/* This is the specific function called from codel_dequeue() ++ * to dequeue a packet from queue. Note: backlog is handled in ++ * codel, we dont need to reduce it here. ++ */ ++static struct sk_buff *dequeue(struct codel_vars *vars, struct Qdisc *sch) ++{ ++ struct sk_buff *skb = __skb_dequeue(&sch->q); ++ ++ prefetch(&skb->end); /* we'll need skb_shinfo() */ ++ return skb; ++} ++ ++static struct sk_buff *codel_qdisc_dequeue(struct Qdisc *sch) ++{ ++ struct codel_sched_data *q = qdisc_priv(sch); ++ struct sk_buff *skb; ++ ++ skb = codel_dequeue(sch, &q->params, &q->vars, &q->stats, dequeue); ++ ++ /* We cant call qdisc_tree_decrease_qlen() if our qlen is 0, ++ * or HTB crashes. Defer it for next round. ++ */ ++ if (q->stats.drop_count && sch->q.qlen) { ++ qdisc_tree_decrease_qlen(sch, q->stats.drop_count); ++ q->stats.drop_count = 0; ++ } ++ if (skb) ++ qdisc_bstats_update(sch, skb); ++ return skb; ++} ++ ++static int codel_qdisc_enqueue(struct sk_buff *skb, struct Qdisc *sch) ++{ ++ struct codel_sched_data *q; ++ ++ q = qdisc_priv(sch); ++ ++#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,39)) ++ if (likely(qdisc_qlen(sch) < q->limit)) { ++#else ++ if (likely(qdisc_qlen(sch) < sch->limit)) { ++#endif ++ codel_set_enqueue_time(skb); ++ return qdisc_enqueue_tail(skb, sch); ++ } ++ q->drop_overlimit++; ++ return qdisc_drop(skb, sch); ++} ++ ++static const struct nla_policy codel_policy[TCA_CODEL_MAX + 1] = { ++ [TCA_CODEL_TARGET] = { .type = NLA_U32 }, ++ [TCA_CODEL_LIMIT] = { .type = NLA_U32 }, ++ [TCA_CODEL_INTERVAL] = { .type = NLA_U32 }, ++ [TCA_CODEL_ECN] = { .type = NLA_U32 }, ++}; ++ ++static int codel_change(struct Qdisc *sch, struct nlattr *opt) ++{ ++ struct codel_sched_data *q = qdisc_priv(sch); ++ struct nlattr *tb[TCA_CODEL_MAX + 1]; ++ unsigned int qlen; ++ int err; ++ ++ if (!opt) ++ return -EINVAL; ++ ++ err = nla_parse_nested(tb, TCA_CODEL_MAX, opt, codel_policy); ++ if (err < 0) ++ return err; ++ ++ sch_tree_lock(sch); ++ ++ if (tb[TCA_CODEL_TARGET]) { ++ u32 target = nla_get_u32(tb[TCA_CODEL_TARGET]); ++ ++ q->params.target = ((u64)target * NSEC_PER_USEC) >> CODEL_SHIFT; ++ } ++ ++ if (tb[TCA_CODEL_INTERVAL]) { ++ u32 interval = nla_get_u32(tb[TCA_CODEL_INTERVAL]); ++ ++ q->params.interval = ((u64)interval * NSEC_PER_USEC) >> CODEL_SHIFT; ++ } ++ ++ if (tb[TCA_CODEL_LIMIT]) ++#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,39)) ++ q->limit = nla_get_u32(tb[TCA_CODEL_LIMIT]); ++#else ++ sch->limit = nla_get_u32(tb[TCA_CODEL_LIMIT]); ++#endif ++ ++ if (tb[TCA_CODEL_ECN]) ++ q->params.ecn = !!nla_get_u32(tb[TCA_CODEL_ECN]); ++ ++ qlen = sch->q.qlen; ++#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,39)) ++ while (sch->q.qlen > q->limit) { ++#else ++ while (sch->q.qlen > sch->limit) { ++#endif ++ struct sk_buff *skb = __skb_dequeue(&sch->q); ++ ++ sch->qstats.backlog -= qdisc_pkt_len(skb); ++ qdisc_drop(skb, sch); ++ } ++ qdisc_tree_decrease_qlen(sch, qlen - sch->q.qlen); ++ ++ sch_tree_unlock(sch); ++ return 0; ++} ++ ++static int codel_init(struct Qdisc *sch, struct nlattr *opt) ++{ ++ struct codel_sched_data *q = qdisc_priv(sch); ++ ++#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,39)) ++ q->limit = DEFAULT_CODEL_LIMIT; ++#else ++ sch->limit = DEFAULT_CODEL_LIMIT; ++#endif ++ ++ codel_params_init(&q->params); ++ codel_vars_init(&q->vars); ++ codel_stats_init(&q->stats); ++ ++ if (opt) { ++ int err = codel_change(sch, opt); ++ ++ if (err) ++ return err; ++ } ++ ++#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,39)) ++ if (q->limit >= 1) ++#else ++ if (sch->limit >= 1) ++#endif ++ sch->flags |= TCQ_F_CAN_BYPASS; ++ else ++ sch->flags &= ~TCQ_F_CAN_BYPASS; ++ ++ return 0; ++} ++ ++static int codel_dump(struct Qdisc *sch, struct sk_buff *skb) ++{ ++ struct codel_sched_data *q = qdisc_priv(sch); ++ struct nlattr *opts; ++ ++ opts = nla_nest_start(skb, TCA_OPTIONS); ++ if (opts == NULL) ++ goto nla_put_failure; ++ ++ if (nla_put_u32(skb, TCA_CODEL_TARGET, ++ codel_time_to_us(q->params.target)) || ++ nla_put_u32(skb, TCA_CODEL_LIMIT, ++#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,39)) ++ q->limit) || ++#else ++ sch->limit) || ++#endif ++ nla_put_u32(skb, TCA_CODEL_INTERVAL, ++ codel_time_to_us(q->params.interval)) || ++ nla_put_u32(skb, TCA_CODEL_ECN, ++ q->params.ecn)) ++ goto nla_put_failure; ++ ++ return nla_nest_end(skb, opts); ++ ++nla_put_failure: ++ nla_nest_cancel(skb, opts); ++ return -1; ++} ++ ++static int codel_dump_stats(struct Qdisc *sch, struct gnet_dump *d) ++{ ++ const struct codel_sched_data *q = qdisc_priv(sch); ++ struct tc_codel_xstats st = { ++ .maxpacket = q->stats.maxpacket, ++ .count = q->vars.count, ++ .lastcount = q->vars.lastcount, ++ .drop_overlimit = q->drop_overlimit, ++ .ldelay = codel_time_to_us(q->vars.ldelay), ++ .dropping = q->vars.dropping, ++ .ecn_mark = q->stats.ecn_mark, ++ }; ++ ++ if (q->vars.dropping) { ++ codel_tdiff_t delta = q->vars.drop_next - codel_get_time(); ++ ++ if (delta >= 0) ++ st.drop_next = codel_time_to_us(delta); ++ else ++ st.drop_next = -codel_time_to_us(-delta); ++ } ++ ++ return gnet_stats_copy_app(d, &st, sizeof(st)); ++} ++ ++static void codel_reset(struct Qdisc *sch) ++{ ++ struct codel_sched_data *q = qdisc_priv(sch); ++ ++ qdisc_reset_queue(sch); ++ codel_vars_init(&q->vars); ++} ++ ++static struct Qdisc_ops codel_qdisc_ops __read_mostly = { ++ .id = "codel", ++ .priv_size = sizeof(struct codel_sched_data), ++ ++ .enqueue = codel_qdisc_enqueue, ++ .dequeue = codel_qdisc_dequeue, ++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,28)) ++ .peek = qdisc_peek_dequeued, ++#endif ++ .init = codel_init, ++ .reset = codel_reset, ++ .change = codel_change, ++ .dump = codel_dump, ++ .dump_stats = codel_dump_stats, ++ .owner = THIS_MODULE, ++}; ++ ++static int __init codel_module_init(void) ++{ ++ return register_qdisc(&codel_qdisc_ops); ++} ++ ++static void __exit codel_module_exit(void) ++{ ++ unregister_qdisc(&codel_qdisc_ops); ++} ++ ++module_init(codel_module_init) ++module_exit(codel_module_exit) ++ ++MODULE_DESCRIPTION("Controlled Delay queue discipline"); ++MODULE_AUTHOR("Dave Taht"); ++MODULE_AUTHOR("Eric Dumazet"); ++MODULE_LICENSE("Dual BSD/GPL"); diff --cc compat/compat/sch_fq_codel_core.c index 000000000000,000000000000..f03df2aba40a new file mode 100644 --- /dev/null +++ b/compat/compat/sch_fq_codel_core.c @@@ -1,0 -1,0 +1,659 @@@ ++/* ++ * Fair Queue CoDel discipline ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * as published by the Free Software Foundation; either version ++ * 2 of the License, or (at your option) any later version. ++ * ++ * Copyright (C) 2012 Eric Dumazet ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* Fair Queue CoDel. ++ * ++ * Principles : ++ * Packets are classified (internal classifier or external) on flows. ++ * This is a Stochastic model (as we use a hash, several flows ++ * might be hashed on same slot) ++ * Each flow has a CoDel managed queue. ++ * Flows are linked onto two (Round Robin) lists, ++ * so that new flows have priority on old ones. ++ * ++ * For a given flow, packets are not reordered (CoDel uses a FIFO) ++ * head drops only. ++ * ECN capability is on by default. ++ * Low memory footprint (64 bytes per flow) ++ */ ++ ++struct fq_codel_flow { ++ struct sk_buff *head; ++ struct sk_buff *tail; ++ struct list_head flowchain; ++ int deficit; ++ u32 dropped; /* number of drops (or ECN marks) on this flow */ ++ struct codel_vars cvars; ++}; /* please try to keep this structure <= 64 bytes */ ++ ++struct fq_codel_sched_data { ++ struct tcf_proto *filter_list; /* optional external classifier */ ++ struct fq_codel_flow *flows; /* Flows table [flows_cnt] */ ++ u32 *backlogs; /* backlog table [flows_cnt] */ ++ u32 flows_cnt; /* number of flows */ ++ u32 perturbation; /* hash perturbation */ ++ u32 quantum; /* psched_mtu(qdisc_dev(sch)); */ ++ struct codel_params cparams; ++ struct codel_stats cstats; ++ u32 drop_overlimit; ++ u32 new_flow_count; ++ ++ struct list_head new_flows; /* list of new flows */ ++ struct list_head old_flows; /* list of old flows */ ++#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,39)) ++ u32 limit; ++#endif ++}; ++ ++static unsigned int fq_codel_hash(const struct fq_codel_sched_data *q, ++ const struct sk_buff *skb) ++{ ++ struct flow_keys keys; ++ unsigned int hash; ++ ++ skb_flow_dissect(skb, &keys); ++ hash = jhash_3words((__force u32)keys.dst, ++ (__force u32)keys.src ^ keys.ip_proto, ++ (__force u32)keys.ports, q->perturbation); ++ return ((u64)hash * q->flows_cnt) >> 32; ++} ++ ++static unsigned int fq_codel_classify(struct sk_buff *skb, struct Qdisc *sch, ++ int *qerr) ++{ ++ struct fq_codel_sched_data *q = qdisc_priv(sch); ++ struct tcf_result res; ++ int result; ++ ++ if (TC_H_MAJ(skb->priority) == sch->handle && ++ TC_H_MIN(skb->priority) > 0 && ++ TC_H_MIN(skb->priority) <= q->flows_cnt) ++ return TC_H_MIN(skb->priority); ++ ++ if (!q->filter_list) ++ return fq_codel_hash(q, skb) + 1; ++ ++ *qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS; ++ result = tc_classify(skb, q->filter_list, &res); ++ if (result >= 0) { ++#ifdef CONFIG_NET_CLS_ACT ++ switch (result) { ++ case TC_ACT_STOLEN: ++ case TC_ACT_QUEUED: ++ *qerr = NET_XMIT_SUCCESS | __NET_XMIT_STOLEN; ++ case TC_ACT_SHOT: ++ return 0; ++ } ++#endif ++ if (TC_H_MIN(res.classid) <= q->flows_cnt) ++ return TC_H_MIN(res.classid); ++ } ++ return 0; ++} ++ ++/* helper functions : might be changed when/if skb use a standard list_head */ ++ ++/* remove one skb from head of slot queue */ ++static inline struct sk_buff *dequeue_head(struct fq_codel_flow *flow) ++{ ++ struct sk_buff *skb = flow->head; ++ ++ flow->head = skb->next; ++ skb->next = NULL; ++ return skb; ++} ++ ++/* add skb to flow queue (tail add) */ ++static inline void flow_queue_add(struct fq_codel_flow *flow, ++ struct sk_buff *skb) ++{ ++ if (flow->head == NULL) ++ flow->head = skb; ++ else ++ flow->tail->next = skb; ++ flow->tail = skb; ++ skb->next = NULL; ++} ++ ++static unsigned int fq_codel_drop(struct Qdisc *sch) ++{ ++ struct fq_codel_sched_data *q = qdisc_priv(sch); ++ struct sk_buff *skb; ++ unsigned int maxbacklog = 0, idx = 0, i, len; ++ struct fq_codel_flow *flow; ++ ++ /* Queue is full! Find the fat flow and drop packet from it. ++ * This might sound expensive, but with 1024 flows, we scan ++ * 4KB of memory, and we dont need to handle a complex tree ++ * in fast path (packet queue/enqueue) with many cache misses. ++ */ ++ for (i = 0; i < q->flows_cnt; i++) { ++ if (q->backlogs[i] > maxbacklog) { ++ maxbacklog = q->backlogs[i]; ++ idx = i; ++ } ++ } ++ flow = &q->flows[idx]; ++ skb = dequeue_head(flow); ++ len = qdisc_pkt_len(skb); ++ q->backlogs[idx] -= len; ++ kfree_skb(skb); ++ sch->q.qlen--; ++ sch->qstats.drops++; ++ sch->qstats.backlog -= len; ++ flow->dropped++; ++ return idx; ++} ++ ++static int fq_codel_enqueue(struct sk_buff *skb, struct Qdisc *sch) ++{ ++ struct fq_codel_sched_data *q = qdisc_priv(sch); ++ unsigned int idx; ++ struct fq_codel_flow *flow; ++ int uninitialized_var(ret); ++ ++ idx = fq_codel_classify(skb, sch, &ret); ++ if (idx == 0) { ++ if (ret & __NET_XMIT_BYPASS) ++ sch->qstats.drops++; ++ kfree_skb(skb); ++ return ret; ++ } ++ idx--; ++ ++ codel_set_enqueue_time(skb); ++ flow = &q->flows[idx]; ++ flow_queue_add(flow, skb); ++ q->backlogs[idx] += qdisc_pkt_len(skb); ++ sch->qstats.backlog += qdisc_pkt_len(skb); ++ ++ if (list_empty(&flow->flowchain)) { ++ list_add_tail(&flow->flowchain, &q->new_flows); ++ codel_vars_init(&flow->cvars); ++ q->new_flow_count++; ++ flow->deficit = q->quantum; ++ flow->dropped = 0; ++ } ++#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,39)) ++ if (++sch->q.qlen < q->limit) ++#else ++ if (++sch->q.qlen < sch->limit) ++#endif ++ return NET_XMIT_SUCCESS; ++ ++ q->drop_overlimit++; ++ /* Return Congestion Notification only if we dropped a packet ++ * from this flow. ++ */ ++ if (fq_codel_drop(sch) == idx) ++ return NET_XMIT_CN; ++ ++ /* As we dropped a packet, better let upper stack know this */ ++ qdisc_tree_decrease_qlen(sch, 1); ++ return NET_XMIT_SUCCESS; ++} ++ ++/* This is the specific function called from codel_dequeue() ++ * to dequeue a packet from queue. Note: backlog is handled in ++ * codel, we dont need to reduce it here. ++ */ ++static struct sk_buff *dequeue(struct codel_vars *vars, struct Qdisc *sch) ++{ ++ struct fq_codel_sched_data *q = qdisc_priv(sch); ++ struct fq_codel_flow *flow; ++ struct sk_buff *skb = NULL; ++ ++ flow = container_of(vars, struct fq_codel_flow, cvars); ++ if (flow->head) { ++ skb = dequeue_head(flow); ++ q->backlogs[flow - q->flows] -= qdisc_pkt_len(skb); ++ sch->q.qlen--; ++ } ++ return skb; ++} ++ ++static struct sk_buff *fq_codel_dequeue(struct Qdisc *sch) ++{ ++ struct fq_codel_sched_data *q = qdisc_priv(sch); ++ struct sk_buff *skb; ++ struct fq_codel_flow *flow; ++ struct list_head *head; ++ u32 prev_drop_count, prev_ecn_mark; ++ ++begin: ++ head = &q->new_flows; ++ if (list_empty(head)) { ++ head = &q->old_flows; ++ if (list_empty(head)) ++ return NULL; ++ } ++ flow = list_first_entry(head, struct fq_codel_flow, flowchain); ++ ++ if (flow->deficit <= 0) { ++ flow->deficit += q->quantum; ++ list_move_tail(&flow->flowchain, &q->old_flows); ++ goto begin; ++ } ++ ++ prev_drop_count = q->cstats.drop_count; ++ prev_ecn_mark = q->cstats.ecn_mark; ++ ++ skb = codel_dequeue(sch, &q->cparams, &flow->cvars, &q->cstats, ++ dequeue); ++ ++ flow->dropped += q->cstats.drop_count - prev_drop_count; ++ flow->dropped += q->cstats.ecn_mark - prev_ecn_mark; ++ ++ if (!skb) { ++ /* force a pass through old_flows to prevent starvation */ ++ if ((head == &q->new_flows) && !list_empty(&q->old_flows)) ++ list_move_tail(&flow->flowchain, &q->old_flows); ++ else ++ list_del_init(&flow->flowchain); ++ goto begin; ++ } ++ qdisc_bstats_update(sch, skb); ++ flow->deficit -= qdisc_pkt_len(skb); ++ /* We cant call qdisc_tree_decrease_qlen() if our qlen is 0, ++ * or HTB crashes. Defer it for next round. ++ */ ++ if (q->cstats.drop_count && sch->q.qlen) { ++ qdisc_tree_decrease_qlen(sch, q->cstats.drop_count); ++ q->cstats.drop_count = 0; ++ } ++ return skb; ++} ++ ++static void fq_codel_reset(struct Qdisc *sch) ++{ ++ struct sk_buff *skb; ++ ++ while ((skb = fq_codel_dequeue(sch)) != NULL) ++ kfree_skb(skb); ++} ++ ++static const struct nla_policy fq_codel_policy[TCA_FQ_CODEL_MAX + 1] = { ++ [TCA_FQ_CODEL_TARGET] = { .type = NLA_U32 }, ++ [TCA_FQ_CODEL_LIMIT] = { .type = NLA_U32 }, ++ [TCA_FQ_CODEL_INTERVAL] = { .type = NLA_U32 }, ++ [TCA_FQ_CODEL_ECN] = { .type = NLA_U32 }, ++ [TCA_FQ_CODEL_FLOWS] = { .type = NLA_U32 }, ++ [TCA_FQ_CODEL_QUANTUM] = { .type = NLA_U32 }, ++}; ++ ++static int fq_codel_change(struct Qdisc *sch, struct nlattr *opt) ++{ ++ struct fq_codel_sched_data *q = qdisc_priv(sch); ++ struct nlattr *tb[TCA_FQ_CODEL_MAX + 1]; ++ int err; ++ ++ if (!opt) ++ return -EINVAL; ++ ++ err = nla_parse_nested(tb, TCA_FQ_CODEL_MAX, opt, fq_codel_policy); ++ if (err < 0) ++ return err; ++ if (tb[TCA_FQ_CODEL_FLOWS]) { ++ if (q->flows) ++ return -EINVAL; ++ q->flows_cnt = nla_get_u32(tb[TCA_FQ_CODEL_FLOWS]); ++ if (!q->flows_cnt || ++ q->flows_cnt > 65536) ++ return -EINVAL; ++ } ++ sch_tree_lock(sch); ++ ++ if (tb[TCA_FQ_CODEL_TARGET]) { ++ u64 target = nla_get_u32(tb[TCA_FQ_CODEL_TARGET]); ++ ++ q->cparams.target = (target * NSEC_PER_USEC) >> CODEL_SHIFT; ++ } ++ ++ if (tb[TCA_FQ_CODEL_INTERVAL]) { ++ u64 interval = nla_get_u32(tb[TCA_FQ_CODEL_INTERVAL]); ++ ++ q->cparams.interval = (interval * NSEC_PER_USEC) >> CODEL_SHIFT; ++ } ++ ++ if (tb[TCA_FQ_CODEL_LIMIT]) ++#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,39)) ++ q->limit = nla_get_u32(tb[TCA_FQ_CODEL_LIMIT]); ++#else ++ sch->limit = nla_get_u32(tb[TCA_FQ_CODEL_LIMIT]); ++#endif ++ ++ if (tb[TCA_FQ_CODEL_ECN]) ++ q->cparams.ecn = !!nla_get_u32(tb[TCA_FQ_CODEL_ECN]); ++ ++ if (tb[TCA_FQ_CODEL_QUANTUM]) ++ q->quantum = max(256U, nla_get_u32(tb[TCA_FQ_CODEL_QUANTUM])); ++ ++#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,39)) ++ while (sch->q.qlen > q->limit) { ++#else ++ while (sch->q.qlen > sch->limit) { ++#endif ++ struct sk_buff *skb = fq_codel_dequeue(sch); ++ ++ kfree_skb(skb); ++ q->cstats.drop_count++; ++ } ++ qdisc_tree_decrease_qlen(sch, q->cstats.drop_count); ++ q->cstats.drop_count = 0; ++ ++ sch_tree_unlock(sch); ++ return 0; ++} ++ ++static void *fq_codel_zalloc(size_t sz) ++{ ++ void *ptr = kzalloc(sz, GFP_KERNEL | __GFP_NOWARN); ++ ++ if (!ptr) ++ ptr = vzalloc(sz); ++ return ptr; ++} ++ ++static void fq_codel_free(void *addr) ++{ ++ if (addr) { ++ if (is_vmalloc_addr(addr)) ++ vfree(addr); ++ else ++ kfree(addr); ++ } ++} ++ ++static void fq_codel_destroy(struct Qdisc *sch) ++{ ++ struct fq_codel_sched_data *q = qdisc_priv(sch); ++ ++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,25)) ++ tcf_destroy_chain(&q->filter_list); ++#else ++ tcf_destroy_chain(q->filter_list); ++#endif ++ fq_codel_free(q->backlogs); ++ fq_codel_free(q->flows); ++} ++ ++static int fq_codel_init(struct Qdisc *sch, struct nlattr *opt) ++{ ++ struct fq_codel_sched_data *q = qdisc_priv(sch); ++ int i; ++ ++#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,39)) ++ q->limit = 10*1024; ++#else ++ sch->limit = 10*1024; ++#endif ++ q->flows_cnt = 1024; ++ q->quantum = psched_mtu(qdisc_dev(sch)); ++ q->perturbation = net_random(); ++ INIT_LIST_HEAD(&q->new_flows); ++ INIT_LIST_HEAD(&q->old_flows); ++ codel_params_init(&q->cparams); ++ codel_stats_init(&q->cstats); ++ q->cparams.ecn = true; ++ ++ if (opt) { ++ int err = fq_codel_change(sch, opt); ++ if (err) ++ return err; ++ } ++ ++ if (!q->flows) { ++ q->flows = fq_codel_zalloc(q->flows_cnt * ++ sizeof(struct fq_codel_flow)); ++ if (!q->flows) ++ return -ENOMEM; ++ q->backlogs = fq_codel_zalloc(q->flows_cnt * sizeof(u32)); ++ if (!q->backlogs) { ++ fq_codel_free(q->flows); ++ return -ENOMEM; ++ } ++ for (i = 0; i < q->flows_cnt; i++) { ++ struct fq_codel_flow *flow = q->flows + i; ++ ++ INIT_LIST_HEAD(&flow->flowchain); ++ } ++ } ++#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,39)) ++ if (q->limit >= 1) ++#else ++ if (sch->limit >= 1) ++#endif ++ sch->flags |= TCQ_F_CAN_BYPASS; ++ else ++ sch->flags &= ~TCQ_F_CAN_BYPASS; ++ return 0; ++} ++ ++static int fq_codel_dump(struct Qdisc *sch, struct sk_buff *skb) ++{ ++ struct fq_codel_sched_data *q = qdisc_priv(sch); ++ struct nlattr *opts; ++ ++ opts = nla_nest_start(skb, TCA_OPTIONS); ++ if (opts == NULL) ++ goto nla_put_failure; ++ ++ if (nla_put_u32(skb, TCA_FQ_CODEL_TARGET, ++ codel_time_to_us(q->cparams.target)) || ++ nla_put_u32(skb, TCA_FQ_CODEL_LIMIT, ++#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,39)) ++ q->limit) || ++#else ++ sch->limit) || ++#endif ++ nla_put_u32(skb, TCA_FQ_CODEL_INTERVAL, ++ codel_time_to_us(q->cparams.interval)) || ++ nla_put_u32(skb, TCA_FQ_CODEL_ECN, ++ q->cparams.ecn) || ++ nla_put_u32(skb, TCA_FQ_CODEL_QUANTUM, ++ q->quantum) || ++ nla_put_u32(skb, TCA_FQ_CODEL_FLOWS, ++ q->flows_cnt)) ++ goto nla_put_failure; ++ ++ nla_nest_end(skb, opts); ++ return skb->len; ++ ++nla_put_failure: ++ return -1; ++} ++ ++static int fq_codel_dump_stats(struct Qdisc *sch, struct gnet_dump *d) ++{ ++ struct fq_codel_sched_data *q = qdisc_priv(sch); ++ struct tc_fq_codel_xstats st = { ++ .type = TCA_FQ_CODEL_XSTATS_QDISC, ++ }; ++ struct list_head *pos; ++ ++ st.qdisc_stats.maxpacket = q->cstats.maxpacket; ++ st.qdisc_stats.drop_overlimit = q->drop_overlimit; ++ st.qdisc_stats.ecn_mark = q->cstats.ecn_mark; ++ st.qdisc_stats.new_flow_count = q->new_flow_count; ++ ++ list_for_each(pos, &q->new_flows) ++ st.qdisc_stats.new_flows_len++; ++ ++ list_for_each(pos, &q->old_flows) ++ st.qdisc_stats.old_flows_len++; ++ ++ return gnet_stats_copy_app(d, &st, sizeof(st)); ++} ++ ++static struct Qdisc *fq_codel_leaf(struct Qdisc *sch, unsigned long arg) ++{ ++ return NULL; ++} ++ ++static unsigned long fq_codel_get(struct Qdisc *sch, u32 classid) ++{ ++ return 0; ++} ++ ++static unsigned long fq_codel_bind(struct Qdisc *sch, unsigned long parent, ++ u32 classid) ++{ ++ /* we cannot bypass queue discipline anymore */ ++ sch->flags &= ~TCQ_F_CAN_BYPASS; ++ return 0; ++} ++ ++static void fq_codel_put(struct Qdisc *q, unsigned long cl) ++{ ++} ++ ++static struct tcf_proto **fq_codel_find_tcf(struct Qdisc *sch, unsigned long cl) ++{ ++ struct fq_codel_sched_data *q = qdisc_priv(sch); ++ ++ if (cl) ++ return NULL; ++ return &q->filter_list; ++} ++ ++static int fq_codel_dump_class(struct Qdisc *sch, unsigned long cl, ++ struct sk_buff *skb, struct tcmsg *tcm) ++{ ++ tcm->tcm_handle |= TC_H_MIN(cl); ++ return 0; ++} ++ ++static int fq_codel_dump_class_stats(struct Qdisc *sch, unsigned long cl, ++ struct gnet_dump *d) ++{ ++ struct fq_codel_sched_data *q = qdisc_priv(sch); ++ u32 idx = cl - 1; ++ struct gnet_stats_queue qs = { 0 }; ++ struct tc_fq_codel_xstats xstats; ++ ++ if (idx < q->flows_cnt) { ++ const struct fq_codel_flow *flow = &q->flows[idx]; ++ const struct sk_buff *skb = flow->head; ++ ++ memset(&xstats, 0, sizeof(xstats)); ++ xstats.type = TCA_FQ_CODEL_XSTATS_CLASS; ++ xstats.class_stats.deficit = flow->deficit; ++ xstats.class_stats.ldelay = ++ codel_time_to_us(flow->cvars.ldelay); ++ xstats.class_stats.count = flow->cvars.count; ++ xstats.class_stats.lastcount = flow->cvars.lastcount; ++ xstats.class_stats.dropping = flow->cvars.dropping; ++ if (flow->cvars.dropping) { ++ codel_tdiff_t delta = flow->cvars.drop_next - ++ codel_get_time(); ++ ++ xstats.class_stats.drop_next = (delta >= 0) ? ++ codel_time_to_us(delta) : ++ -codel_time_to_us(-delta); ++ } ++ while (skb) { ++ qs.qlen++; ++ skb = skb->next; ++ } ++ qs.backlog = q->backlogs[idx]; ++ qs.drops = flow->dropped; ++ } ++ if (gnet_stats_copy_queue(d, &qs) < 0) ++ return -1; ++ if (idx < q->flows_cnt) ++ return gnet_stats_copy_app(d, &xstats, sizeof(xstats)); ++ return 0; ++} ++ ++static void fq_codel_walk(struct Qdisc *sch, struct qdisc_walker *arg) ++{ ++ struct fq_codel_sched_data *q = qdisc_priv(sch); ++ unsigned int i; ++ ++ if (arg->stop) ++ return; ++ ++ for (i = 0; i < q->flows_cnt; i++) { ++ if (list_empty(&q->flows[i].flowchain) || ++ arg->count < arg->skip) { ++ arg->count++; ++ continue; ++ } ++ if (arg->fn(sch, i + 1, arg) < 0) { ++ arg->stop = 1; ++ break; ++ } ++ arg->count++; ++ } ++} ++ ++static const struct Qdisc_class_ops fq_codel_class_ops = { ++ .leaf = fq_codel_leaf, ++ .get = fq_codel_get, ++ .put = fq_codel_put, ++ .tcf_chain = fq_codel_find_tcf, ++ .bind_tcf = fq_codel_bind, ++ .unbind_tcf = fq_codel_put, ++ .dump = fq_codel_dump_class, ++ .dump_stats = fq_codel_dump_class_stats, ++ .walk = fq_codel_walk, ++}; ++ ++static struct Qdisc_ops fq_codel_qdisc_ops __read_mostly = { ++ .cl_ops = &fq_codel_class_ops, ++ .id = "fq_codel", ++ .priv_size = sizeof(struct fq_codel_sched_data), ++ .enqueue = fq_codel_enqueue, ++ .dequeue = fq_codel_dequeue, ++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,28)) ++ .peek = qdisc_peek_dequeued, ++#endif ++ .drop = fq_codel_drop, ++ .init = fq_codel_init, ++ .reset = fq_codel_reset, ++ .destroy = fq_codel_destroy, ++ .change = fq_codel_change, ++ .dump = fq_codel_dump, ++ .dump_stats = fq_codel_dump_stats, ++ .owner = THIS_MODULE, ++}; ++ ++static int __init fq_codel_module_init(void) ++{ ++ return register_qdisc(&fq_codel_qdisc_ops); ++} ++ ++static void __exit fq_codel_module_exit(void) ++{ ++ unregister_qdisc(&fq_codel_qdisc_ops); ++} ++ ++module_init(fq_codel_module_init) ++module_exit(fq_codel_module_exit) ++MODULE_AUTHOR("Eric Dumazet"); ++MODULE_LICENSE("GPL"); diff --cc compat/compat/user_namespace.c index 000000000000,000000000000..0dcc4bcfb9ab new file mode 100644 --- /dev/null +++ b/compat/compat/user_namespace.c @@@ -1,0 -1,0 +1,68 @@@ ++/* ++ * Copyright 2012 Luis R. Rodriguez ++ * ++ * 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 backporting ++ * user_namespace.c ++ */ ++ ++#include ++#include ++#include ++ ++#ifdef CONFIG_USER_NS ++ ++kuid_t make_kuid(struct user_namespace *ns, uid_t uid) ++{ ++ /* Map the uid to a global kernel uid */ ++ return KUIDT_INIT(uid); ++} ++EXPORT_SYMBOL_GPL(make_kuid); ++ ++uid_t from_kuid(struct user_namespace *targ, kuid_t kuid) ++{ ++ /* Map the uid from a global kernel uid */ ++ return __kuid_val(kuid); ++} ++EXPORT_SYMBOL_GPL(from_kuid); ++ ++uid_t from_kuid_munged(struct user_namespace *targ, kuid_t kuid) ++{ ++ uid_t uid; ++ uid = from_kuid(targ, kuid); ++ ++ if (uid == (uid_t) -1) ++ uid = overflowuid; ++ return uid; ++} ++EXPORT_SYMBOL_GPL(from_kuid_munged); ++ ++kgid_t make_kgid(struct user_namespace *ns, gid_t gid) ++{ ++ /* Map the gid to a global kernel gid */ ++ return KGIDT_INIT(gid); ++} ++EXPORT_SYMBOL_GPL(make_kgid); ++ ++gid_t from_kgid(struct user_namespace *targ, kgid_t kgid) ++{ ++ /* Map the gid from a global kernel gid */ ++ return __kgid_val(kgid); ++} ++EXPORT_SYMBOL_GPL(from_kgid); ++ ++gid_t from_kgid_munged(struct user_namespace *targ, kgid_t kgid) ++{ ++ gid_t gid; ++ gid = from_kgid(targ, kgid); ++ ++ if (gid == (gid_t) -1) ++ gid = overflowgid; ++ return gid; ++} ++EXPORT_SYMBOL_GPL(from_kgid_munged); ++ ++#endif /* CONFIG_USER_NS */ diff --cc compat/include/crypto/aes.h index 000000000000,000000000000..8031a54d4a45 new file mode 100644 --- /dev/null +++ b/compat/include/crypto/aes.h @@@ -1,0 -1,0 +1,21 @@@ ++#ifndef _COMPAT_CRYPTO_AES_H ++#define _COMPAT_CRYPTO_AES_H ++ ++#include ++ ++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,24)) ++#include_next ++#else ++ ++#define AES_MIN_KEY_SIZE 16 ++#define AES_MAX_KEY_SIZE 32 ++#define AES_KEYSIZE_128 16 ++#define AES_KEYSIZE_192 24 ++#define AES_KEYSIZE_256 32 ++#define AES_BLOCK_SIZE 16 ++#define AES_MAX_KEYLENGTH (15 * 16) ++#define AES_MAX_KEYLENGTH_U32 (AES_MAX_KEYLENGTH / sizeof(u32)) ++ ++#endif /* (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,24)) */ ++ ++#endif diff --cc compat/include/linux/atomic.h index 000000000000,000000000000..378b748fb207 new file mode 100644 --- /dev/null +++ b/compat/include/linux/atomic.h @@@ -1,0 -1,0 +1,46 @@@ ++#ifndef _COMPAT_LINUX_ATOMIC_H ++#define _COMPAT_LINUX_ATOMIC_H 1 ++ ++#include ++ ++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,36)) ++#include_next ++#else ++ ++#include ++ ++/** ++ * atomic_inc_not_zero_hint - increment if not null ++ * @v: pointer of type atomic_t ++ * @hint: probable value of the atomic before the increment ++ * ++ * This version of atomic_inc_not_zero() gives a hint of probable ++ * value of the atomic. This helps processor to not read the memory ++ * before doing the atomic read/modify/write cycle, lowering ++ * number of bus transactions on some arches. ++ * ++ * Returns: 0 if increment was not done, 1 otherwise. ++ */ ++#ifndef atomic_inc_not_zero_hint ++static inline int atomic_inc_not_zero_hint(atomic_t *v, int hint) ++{ ++ int val, c = hint; ++ ++ /* sanity test, should be removed by compiler if hint is a constant */ ++ if (!hint) ++ return atomic_inc_not_zero(v); ++ ++ do { ++ val = atomic_cmpxchg(v, c, c + 1); ++ if (val == c) ++ return 1; ++ c = val; ++ } while (c); ++ ++ return 0; ++} ++#endif ++ ++#endif /* (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,36)) */ ++ ++#endif /* _COMPAT_LINUX_ATOMIC_H */ diff --cc compat/include/linux/average.h index 000000000000,000000000000..ece86ca3a971 new file mode 100644 --- /dev/null +++ b/compat/include/linux/average.h @@@ -1,0 -1,0 +1,5 @@@ ++#include ++ ++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,37)) ++#include_next ++#endif /* (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,37)) */ diff --cc compat/include/linux/bitops.h index 000000000000,000000000000..aa76af184344 new file mode 100644 --- /dev/null +++ b/compat/include/linux/bitops.h @@@ -1,0 -1,0 +1,211 @@@ ++#ifndef _LINUX_BITOPS_H ++#define _LINUX_BITOPS_H ++#include ++ ++#ifdef __KERNEL__ ++#define BIT(nr) (1UL << (nr)) ++#define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG)) ++#define BIT_WORD(nr) ((nr) / BITS_PER_LONG) ++#define BITS_PER_BYTE 8 ++#ifndef BITS_TO_LONGS /* Older kernels define this already */ ++#define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long)) ++#endif ++#endif ++ ++extern unsigned int __sw_hweight8(unsigned int w); ++extern unsigned int __sw_hweight16(unsigned int w); ++extern unsigned int __sw_hweight32(unsigned int w); ++extern unsigned long __sw_hweight64(__u64 w); ++ ++/* ++ * Include this here because some architectures need generic_ffs/fls in ++ * scope ++ */ ++#include ++ ++#define for_each_set_bit(bit, addr, size) \ ++ for ((bit) = find_first_bit((addr), (size)); \ ++ (bit) < (size); \ ++ (bit) = find_next_bit((addr), (size), (bit) + 1)) ++ ++static __inline__ int get_bitmask_order(unsigned int count) ++{ ++ int order; ++ ++ order = fls(count); ++ return order; /* We could be slightly more clever with -1 here... */ ++} ++ ++static __inline__ int get_count_order(unsigned int count) ++{ ++ int order; ++ ++ order = fls(count) - 1; ++ if (count & (count - 1)) ++ order++; ++ return order; ++} ++ ++static inline unsigned long hweight_long(unsigned long w) ++{ ++ return sizeof(w) == 4 ? hweight32(w) : hweight64(w); ++} ++ ++/** ++ * rol32 - rotate a 32-bit value left ++ * @word: value to rotate ++ * @shift: bits to roll ++ */ ++static inline __u32 rol32(__u32 word, unsigned int shift) ++{ ++ return (word << shift) | (word >> (32 - shift)); ++} ++ ++/** ++ * ror32 - rotate a 32-bit value right ++ * @word: value to rotate ++ * @shift: bits to roll ++ */ ++static inline __u32 ror32(__u32 word, unsigned int shift) ++{ ++ return (word >> shift) | (word << (32 - shift)); ++} ++ ++/** ++ * rol16 - rotate a 16-bit value left ++ * @word: value to rotate ++ * @shift: bits to roll ++ */ ++static inline __u16 rol16(__u16 word, unsigned int shift) ++{ ++ return (word << shift) | (word >> (16 - shift)); ++} ++ ++/** ++ * ror16 - rotate a 16-bit value right ++ * @word: value to rotate ++ * @shift: bits to roll ++ */ ++static inline __u16 ror16(__u16 word, unsigned int shift) ++{ ++ return (word >> shift) | (word << (16 - shift)); ++} ++ ++/** ++ * rol8 - rotate an 8-bit value left ++ * @word: value to rotate ++ * @shift: bits to roll ++ */ ++static inline __u8 rol8(__u8 word, unsigned int shift) ++{ ++ return (word << shift) | (word >> (8 - shift)); ++} ++ ++/** ++ * ror8 - rotate an 8-bit value right ++ * @word: value to rotate ++ * @shift: bits to roll ++ */ ++static inline __u8 ror8(__u8 word, unsigned int shift) ++{ ++ return (word >> shift) | (word << (8 - shift)); ++} ++ ++/** ++ * sign_extend32 - sign extend a 32-bit value using specified bit as sign-bit ++ * @value: value to sign extend ++ * @index: 0 based bit index (0<=index<32) to sign bit ++ */ ++static inline __s32 sign_extend32(__u32 value, int index) ++{ ++ __u8 shift = 31 - index; ++ return (__s32)(value << shift) >> shift; ++} ++ ++static inline unsigned fls_long(unsigned long l) ++{ ++ if (sizeof(l) == 4) ++ return fls(l); ++ return fls64(l); ++} ++ ++/** ++ * __ffs64 - find first set bit in a 64 bit word ++ * @word: The 64 bit word ++ * ++ * On 64 bit arches this is a synomyn for __ffs ++ * The result is not defined if no bits are set, so check that @word ++ * is non-zero before calling this. ++ */ ++static inline unsigned long __ffs64(u64 word) ++{ ++#if BITS_PER_LONG == 32 ++ if (((u32)word) == 0UL) ++ return __ffs((u32)(word >> 32)) + 32; ++#elif BITS_PER_LONG != 64 ++#error BITS_PER_LONG not 32 or 64 ++#endif ++ return __ffs((unsigned long)word); ++} ++ ++#ifdef __KERNEL__ ++#ifdef CONFIG_GENERIC_FIND_FIRST_BIT ++ ++/** ++ * find_first_bit - find the first set bit in a memory region ++ * @addr: The address to start the search at ++ * @size: The maximum size to search ++ * ++ * Returns the bit number of the first set bit. ++ */ ++extern unsigned long find_first_bit(const unsigned long *addr, ++ unsigned long size); ++ ++/** ++ * find_first_zero_bit - find the first cleared bit in a memory region ++ * @addr: The address to start the search at ++ * @size: The maximum size to search ++ * ++ * Returns the bit number of the first cleared bit. ++ */ ++extern unsigned long find_first_zero_bit(const unsigned long *addr, ++ unsigned long size); ++#endif /* CONFIG_GENERIC_FIND_FIRST_BIT */ ++ ++#ifdef CONFIG_GENERIC_FIND_LAST_BIT ++/** ++ * find_last_bit - find the last set bit in a memory region ++ * @addr: The address to start the search at ++ * @size: The maximum size to search ++ * ++ * Returns the bit number of the first set bit, or size. ++ */ ++extern unsigned long find_last_bit(const unsigned long *addr, ++ unsigned long size); ++#endif /* CONFIG_GENERIC_FIND_LAST_BIT */ ++ ++#ifdef CONFIG_GENERIC_FIND_NEXT_BIT ++ ++/** ++ * find_next_bit - find the next set bit in a memory region ++ * @addr: The address to base the search on ++ * @offset: The bitnumber to start searching at ++ * @size: The bitmap size in bits ++ */ ++extern unsigned long find_next_bit(const unsigned long *addr, ++ unsigned long size, unsigned long offset); ++ ++/** ++ * find_next_zero_bit - find the next cleared bit in a memory region ++ * @addr: The address to base the search on ++ * @offset: The bitnumber to start searching at ++ * @size: The bitmap size in bits ++ */ ++ ++extern unsigned long find_next_zero_bit(const unsigned long *addr, ++ unsigned long size, ++ unsigned long offset); ++ ++#endif /* CONFIG_GENERIC_FIND_NEXT_BIT */ ++#endif /* __KERNEL__ */ ++#endif diff --cc compat/include/linux/compat-2.6.14.h index 000000000000,000000000000..1f19f7fee562 new file mode 100644 --- /dev/null +++ b/compat/include/linux/compat-2.6.14.h @@@ -1,0 -1,0 +1,13 @@@ ++#ifndef LINUX_26_14_COMPAT_H ++#define LINUX_26_14_COMPAT_H ++ ++#include ++ ++/* Compat work for 2.6.14 */ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14)) ++ ++typedef unsigned int gfp_t; ++ ++#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14)) */ ++ ++#endif /* LINUX_26_14_COMPAT_H */ diff --cc compat/include/linux/compat-2.6.18.h index 000000000000,000000000000..5e0182b18a16 new file mode 100644 --- /dev/null +++ b/compat/include/linux/compat-2.6.18.h @@@ -1,0 -1,0 +1,13 @@@ ++#ifndef LINUX_26_18_COMPAT_H ++#define LINUX_26_18_COMPAT_H ++ ++#include ++ ++/* Compat work for 2.6.18 */ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)) ++ ++#define roundup(x, y) ((((x) + ((y) - 1)) / (y)) * (y)) ++ ++#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)) */ ++ ++#endif /* LINUX_26_18_COMPAT_H */ diff --cc compat/include/linux/compat-2.6.19.h index 000000000000,000000000000..1e648c0aeba6 new file mode 100644 --- /dev/null +++ b/compat/include/linux/compat-2.6.19.h @@@ -1,0 -1,0 +1,24 @@@ ++#ifndef LINUX_26_19_COMPAT_H ++#define LINUX_26_19_COMPAT_H ++ ++#include ++ ++/* Compat work for 2.6.19 */ ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)) ++ ++#include ++ ++static inline int ++compat_kmem_cache_destroy(struct kmem_cache *cachep) ++{ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)) ++ return kmem_cache_destroy(cachep); ++#else ++ kmem_cache_destroy(cachep); ++ return 0; ++#endif ++} ++ ++#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)) */ ++ ++#endif /* LINUX_26_19_COMPAT_H */ diff --cc compat/include/linux/compat-2.6.20.h index 000000000000,000000000000..14579e29cf8e new file mode 100644 --- /dev/null +++ b/compat/include/linux/compat-2.6.20.h @@@ -1,0 -1,0 +1,21 @@@ ++#ifndef LINUX_26_20_COMPAT_H ++#define LINUX_26_20_COMPAT_H ++ ++#include ++ ++/* Compat work for 2.6.20 */ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)) ++ ++#include ++ ++typedef void (*work_func_t)(struct work_struct *work); ++typedef void (*compat_work_func_t)(void *work); ++static inline void (INIT_WORK)(struct work_struct *work, work_func_t func) ++{ ++ INIT_WORK(work, (compat_work_func_t)func, work); ++} ++#undef INIT_WORK ++ ++#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)) */ ++ ++#endif /* LINUX_26_20_COMPAT_H */ diff --cc compat/include/linux/compat-2.6.21.h index 000000000000,000000000000..89ed6d9a4358 new file mode 100644 --- /dev/null +++ b/compat/include/linux/compat-2.6.21.h @@@ -1,0 -1,0 +1,18 @@@ ++#ifndef LINUX_26_21_COMPAT_H ++#define LINUX_26_21_COMPAT_H ++ ++#include ++ ++/* Compat work for 2.6.21 */ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) ++ ++#include ++ ++#define register_sysctl_table(table) \ ++ ({ \ ++ register_sysctl_table((table), 0); \ ++ }) ++ ++#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) */ ++ ++#endif /* LINUX_26_21_COMPAT_H */ diff --cc compat/include/linux/compat-2.6.22.h index 000000000000,000000000000..7ca1b18ea0f3 new file mode 100644 --- /dev/null +++ b/compat/include/linux/compat-2.6.22.h @@@ -1,0 -1,0 +1,104 @@@ ++#ifndef LINUX_26_22_COMPAT_H ++#define LINUX_26_22_COMPAT_H ++ ++#include ++ ++/* Compat work for 2.6.21 */ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22)) ++ ++#include ++#include ++ ++/* reuse ax25_ptr */ ++#define ieee80211_ptr ax25_ptr ++ ++#ifdef CONFIG_AX25 ++#error Compat reuses the AX.25 pointer so that may not be enabled! ++#endif ++ ++static inline unsigned char *skb_mac_header(const struct sk_buff *skb) ++{ ++ return skb->mac.raw; ++} ++ ++static inline void skb_set_mac_header(struct sk_buff *skb, int offset) ++{ ++ skb->mac.raw = skb->data + offset; ++} ++ ++static inline void skb_reset_mac_header(struct sk_buff *skb) ++{ ++ skb->mac.raw = skb->data; ++} ++ ++static inline void skb_reset_network_header(struct sk_buff *skb) ++{ ++ skb->nh.raw = skb->data; ++} ++ ++static inline void skb_set_network_header(struct sk_buff *skb, int offset) ++{ ++ skb->nh.raw = skb->data + offset; ++} ++ ++static inline void skb_set_transport_header(struct sk_buff *skb, int offset) ++{ ++ skb->h.raw = skb->data + offset; ++} ++ ++static inline unsigned char *skb_transport_header(struct sk_buff *skb) ++{ ++ return skb->h.raw; ++} ++ ++static inline unsigned char *skb_network_header(const struct sk_buff *skb) ++{ ++ return skb->nh.raw; ++} ++ ++static inline unsigned char *skb_tail_pointer(const struct sk_buff *skb) ++{ ++ return skb->tail; ++} ++ ++static inline struct iphdr *ip_hdr(const struct sk_buff *skb) ++{ ++ return (struct iphdr *)skb_network_header(skb); ++} ++ ++static inline void skb_copy_from_linear_data(const struct sk_buff *skb, ++ void *to, ++ const unsigned int len) ++{ ++ memcpy(to, skb->data, len); ++} ++ ++static inline void skb_copy_from_linear_data_offset(const struct sk_buff *skb, ++ const int offset, void *to, ++ const unsigned int len) ++{ ++ memcpy(to, skb->data + offset, len); ++} ++ ++#define __maybe_unused __attribute__((unused)) ++ ++#define uninitialized_var(x) x = x ++ ++/* This will lead to very weird behaviour... */ ++#define NLA_BINARY NLA_STRING ++ ++static inline int pci_set_mwi(struct pci_dev *dev) ++{ ++ return -ENOSYS; ++} ++ ++static inline void pci_clear_mwi(struct pci_dev *dev) ++{ ++} ++ ++#define list_first_entry(ptr, type, member) \ ++ list_entry((ptr)->next, type, member) ++ ++#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22)) */ ++ ++#endif /* LINUX_26_22_COMPAT_H */ diff --cc compat/include/linux/compat-2.6.23.h index 000000000000,000000000000..37cbc22a6670 new file mode 100644 --- /dev/null +++ b/compat/include/linux/compat-2.6.23.h @@@ -1,0 -1,0 +1,139 @@@ ++#ifndef LINUX_26_23_COMPAT_H ++#define LINUX_26_23_COMPAT_H ++ ++#include ++ ++/* Compat work for < 2.6.23 */ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)) ++ ++#include ++#include ++#include ++#include ++#include ++ ++/* ++ * Tell gcc if a function is cold. The compiler will assume any path ++ * directly leading to the call is unlikely. ++ */ ++ ++#if !(__GNUC__ == 4 && __GNUC_MINOR__ < 3) ++/* Mark functions as cold. gcc will assume any path leading to a call ++ * to them will be unlikely. This means a lot of manual unlikely()s ++ * are unnecessary now for any paths leading to the usual suspects ++ * like BUG(), printk(), panic() etc. [but let's keep them for now for ++ * older compilers] ++ * ++ * Early snapshots of gcc 4.3 don't support this and we can't detect this ++ * in the preprocessor, but we can live with this because they're unreleased. ++ * Maketime probing would be overkill here. ++ * ++ * gcc also has a __attribute__((__hot__)) to move hot functions into ++ * a special section, but I don't see any sense in this right now in ++ * the kernel context */ ++#define __cold __attribute__((__cold__)) ++#endif /* gcc 4.3 check */ ++ ++#ifndef __cold ++#define __cold ++#endif ++ ++/* Added as of 2.6.23 in include/linux/netdevice.h */ ++#define alloc_netdev_mq(sizeof_priv, name, setup, queue) \ ++ alloc_netdev(sizeof_priv, name, setup) ++#define NETIF_F_MULTI_QUEUE 16384 ++ ++/* Added as of 2.6.23 on include/linux/netdevice.h */ ++static inline int netif_is_multiqueue(const struct net_device *dev) ++{ ++ return (!!(NETIF_F_MULTI_QUEUE & dev->features)); ++} ++ ++/* 2.6.23 fixed a bug in tcf_destroy_chain and the parameter changed */ ++static inline void tcf_destroy_chain_compat(struct tcf_proto **fl) ++{ ++ struct tcf_proto *tp; ++ ++ while ((tp = *fl) != NULL) { ++ *fl = tp->next; ++ tp->ops->destroy(tp); ++ module_put(tp->ops->owner); ++ kfree(tp); ++ } ++} ++ ++/* dev_mc_list was replaced with dev_addr_list as of 2.6.23, ++ * only new member added is da_synced. */ ++#define dev_addr_list dev_mc_list ++#define da_addr dmi_addr ++#define da_addrlen dmi_addrlen ++#define da_users dmi_users ++#define da_gusers dmi_gusers ++ ++/* dev_set_promiscuity() was moved to __dev_set_promiscuity() on 2.6.23 and ++ * dev_set_promiscuity() became a wrapper. */ ++#define __dev_set_promiscuity dev_set_promiscuity ++ ++/* Our own 2.6.22 port on compat.c */ ++#define dev_mc_unsync LINUX_BACKPORT(dev_mc_unsync) ++#define dev_mc_sync LINUX_BACKPORT(dev_mc_sync) ++extern void dev_mc_unsync(struct net_device *to, struct net_device *from); ++extern int dev_mc_sync(struct net_device *to, struct net_device *from); ++ ++/* Our own 2.6.22 port on compat.c */ ++extern void __dev_set_rx_mode(struct net_device *dev); ++ ++/* Simple to add this */ ++extern int cancel_delayed_work_sync(struct delayed_work *work); ++ ++#define cancel_delayed_work_sync cancel_rearming_delayed_work ++ ++#define debugfs_rename(a, b, c, d) 1 ++ ++/* nl80211 requires multicast group support which is new and added on ++ * 2.6.23. We can't add support for it for older kernels to support it ++ * genl_family structure was changed. Lets just let through the ++ * genl_register_mc_group call. This means no multicast group suppport */ ++ ++#define genl_register_mc_group(a, b) 0 ++ ++/** ++ * struct genl_multicast_group - generic netlink multicast group ++ * @name: name of the multicast group, names are per-family ++ * @id: multicast group ID, assigned by the core, to use with ++ * genlmsg_multicast(). ++ * @list: list entry for linking ++ * @family: pointer to family, need not be set before registering ++ */ ++struct genl_multicast_group ++{ ++ struct genl_family *family; /* private */ ++ struct list_head list; /* private */ ++ char name[GENL_NAMSIZ]; ++ u32 id; ++}; ++ ++ ++/* Added as of 2.6.23 */ ++#define pci_try_set_mwi LINUX_BACKPORT(pci_try_set_mwi) ++int pci_try_set_mwi(struct pci_dev *dev); ++ ++/* Added as of 2.6.23 */ ++#ifdef CONFIG_PM_SLEEP ++/* ++ * Tell the freezer that the current task should be frozen by it ++ */ ++static inline void set_freezable(void) ++{ ++ current->flags &= ~PF_NOFREEZE; ++} ++ ++#else ++static inline void set_freezable(void) {} ++#endif /* CONFIG_PM_SLEEP */ ++ ++#else ++#define tcf_destroy_chain_compat tcf_destroy_chain ++#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)) */ ++ ++#endif /* LINUX_26_23_COMPAT_H */ diff --cc compat/include/linux/compat-2.6.24.h index 000000000000,000000000000..5448604cdbb2 new file mode 100644 --- /dev/null +++ b/compat/include/linux/compat-2.6.24.h @@@ -1,0 -1,0 +1,252 @@@ ++#ifndef LINUX_26_24_COMPAT_H ++#define LINUX_26_24_COMPAT_H ++ ++#include ++ ++/* Compat work for 2.6.21, 2.6.22 and 2.6.23 */ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)) ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define KEY_BLUETOOTH 237 ++#define KEY_WLAN 238 ++#define KEY_UWB 239 ++ ++#define DMA_BIT_MASK(n) (((n) == 64) ? ~0ULL : ((1ULL<<(n))-1)) ++ ++struct proc_dir_entry; ++struct net_device; ++struct net { ++ atomic_t count; /* To decided when the network ++ * namespace should be freed. ++ */ ++ atomic_t use_count; /* To track references we ++ * destroy on demand ++ */ ++ struct list_head list; /* list of network namespaces */ ++ struct work_struct work; /* work struct for freeing */ ++ ++ struct proc_dir_entry *proc_net; ++ struct proc_dir_entry *proc_net_stat; ++ struct proc_dir_entry *proc_net_root; ++ ++ struct net_device *loopback_dev; /* The loopback */ ++ ++ struct list_head dev_base_head; ++ struct hlist_head *dev_name_head; ++ struct hlist_head *dev_index_head; ++}; ++ ++#ifdef CONFIG_NET ++/* Init's network namespace */ ++#define init_net LINUX_BACKPORT(init_net) ++extern struct net init_net; ++#define INIT_NET_NS(net_ns) .net_ns = &init_net, ++#else ++#define INIT_NET_NS(net_ns) ++#endif ++ ++/* Added on 2.6.24 in include/linux/types.h by Al viro on commit 142956af */ ++typedef unsigned long uintptr_t; ++ ++/* From include/linux/net.h */ ++enum sock_shutdown_cmd { ++ SHUT_RD = 0, ++ SHUT_WR = 1, ++ SHUT_RDWR = 2, ++}; ++ ++#if (LINUX_VERSION_CODE == KERNEL_VERSION(2,6,23)) /* Local check */ ++/* Added as of 2.6.24 in include/linux/skbuff.h. ++ * ++ * Although 2.6.23 does support for CONFIG_NETDEVICES_MULTIQUEUE ++ * this helper was not added until 2.6.24. This implementation ++ * is exactly as it is on newer kernels. ++ * ++ * For older kernels we use the an internal mac80211 hack. ++ * For details see changes to include/net/mac80211.h through ++ * compat.diff and compat/mq_compat.h */ ++static inline u16 skb_get_queue_mapping(struct sk_buff *skb) ++{ ++#ifdef CONFIG_NETDEVICES_MULTIQUEUE ++ return skb->queue_mapping; ++#else ++ return 0; ++#endif ++} ++#endif /* Local 2.6.23 check */ ++ ++/* On older kernels we handle this a bit differently, so we yield to that ++ * code for its implementation in mq_compat.h as we want to make ++ * use of the internal mac80211 __ieee80211_queue_stopped() which itself ++ * uses internal mac80211 data structure hacks. */ ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23)) /* Local check */ ++/** ++ * netif_subqueue_stopped - test status of subqueue ++ * @dev: network device ++ * @queue_index: sub queue index ++ * ++ * Check individual transmit queue of a device with multiple transmit queues. ++ */ ++static inline int __netif_subqueue_stopped(const struct net_device *dev, ++ u16 queue_index) ++{ ++#ifdef CONFIG_NETDEVICES_MULTIQUEUE ++ return test_bit(__LINK_STATE_XOFF, ++ &dev->egress_subqueue[queue_index].state); ++#else ++ return 0; ++#endif ++} ++ ++/* Note: although the backport implementation for netif_subqueue_stopped ++ * on older kernels is identical to upstream __netif_subqueue_stopped() ++ * (except for a const qualifier) we implement netif_subqueue_stopped() ++ * as part of mac80211 as it relies on internal mac80211 structures we ++ * use for MQ support. We this implement it in mq_compat.h */ ++ ++#endif /* Local 2.6.23 check */ ++ ++/* ++ * Force link bug if constructor is used, can't be done compatibly ++ * because constructor arguments were swapped since then! ++ */ ++extern void __incompatible_kmem_cache_create(void); ++ ++/* 2.6.21 and 2.6.22 kmem_cache_create() takes 6 arguments */ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)) ++#define kmem_cache_create(name, objsize, align, flags, ctor) \ ++ ({ \ ++ if (ctor) __incompatible_kmem_cache_create(); \ ++ kmem_cache_create((name), (objsize), (align), \ ++ (flags), NULL, NULL); \ ++ }) ++#endif ++ ++/* 2.6.23 kmem_cache_create() takes 5 arguments */ ++#if (LINUX_VERSION_CODE == KERNEL_VERSION(2,6,23)) ++#define kmem_cache_create(name, objsize, align, flags, ctor) \ ++ ({ \ ++ if (ctor) __incompatible_kmem_cache_create(); \ ++ kmem_cache_create((name), (objsize), (align), \ ++ (flags), NULL); \ ++ }) ++#endif ++ ++/* From include/linux/mod_devicetable.h */ ++ ++/* SSB core, see drivers/ssb/ */ ++#ifndef SSB_DEVICE ++struct ssb_device_id { ++ __u16 vendor; ++ __u16 coreid; ++ __u8 revision; ++}; ++#define SSB_DEVICE(_vendor, _coreid, _revision) \ ++ { .vendor = _vendor, .coreid = _coreid, .revision = _revision, } ++#define SSB_DEVTABLE_END \ ++ { 0, }, ++ ++#define SSB_ANY_VENDOR 0xFFFF ++#define SSB_ANY_ID 0xFFFF ++#define SSB_ANY_REV 0xFF ++#endif ++ ++ ++/* Namespace stuff, introduced on 2.6.24 */ ++#define dev_get_by_index(a, b) dev_get_by_index(b) ++#define __dev_get_by_index(a, b) __dev_get_by_index(b) ++ ++#define eth_header LINUX_BACKPORT(eth_header) ++extern int eth_header(struct sk_buff *skb, struct net_device *dev, ++ unsigned short type, void *daddr, ++ void *saddr, unsigned len); ++#define eth_rebuild_header LINUX_BACKPORT(eth_rebuild_header) ++extern int eth_rebuild_header(struct sk_buff *skb); ++#define eth_header_cache_update LINUX_BACKPORT(eth_header_cache_update) ++extern void eth_header_cache_update(struct hh_cache *hh, struct net_device *dev, ++ unsigned char * haddr); ++#define eth_header_cache LINUX_BACKPORT(eth_header_cache) ++extern int eth_header_cache(struct neighbour *neigh, ++ struct hh_cache *hh); ++ ++/* This structure is simply not present on 2.6.22 and 2.6.23 */ ++struct header_ops { ++ int (*create) (struct sk_buff *skb, struct net_device *dev, ++ unsigned short type, void *daddr, ++ void *saddr, unsigned len); ++ int (*parse)(const struct sk_buff *skb, unsigned char *haddr); ++ int (*rebuild)(struct sk_buff *skb); ++ #define HAVE_HEADER_CACHE ++ int (*cache)(struct neighbour *neigh, struct hh_cache *hh); ++ void (*cache_update)(struct hh_cache *hh, ++ struct net_device *dev, ++ unsigned char *haddr); ++}; ++ ++/* net/ieee80211/ieee80211_crypt_tkip uses sg_init_table. This was added on ++ * 2.6.24. CONFIG_DEBUG_SG was added in 2.6.24 as well, so lets just ignore ++ * the debug stuff. Note that adding this required changes to the struct ++ * scatterlist on include/asm/scatterlist*, so the right way to port this ++ * is to simply ignore the new structure changes and zero the scatterlist ++ * array. We lave the kdoc intact for reference. ++ */ ++ ++/** ++ * sg_mark_end - Mark the end of the scatterlist ++ * @sg: SG entryScatterlist ++ * ++ * Description: ++ * Marks the passed in sg entry as the termination point for the sg ++ * table. A call to sg_next() on this entry will return NULL. ++ * ++ **/ ++static inline void sg_mark_end(struct scatterlist *sg) ++{ ++#ifdef CONFIG_DEBUG_SG ++ BUG_ON(sg->sg_magic != SG_MAGIC); ++#endif ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)) ++ /* ++ * Set termination bit, clear potential chain bit ++ */ ++ sg->page_link |= 0x02; ++ sg->page_link &= ~0x01; ++#endif ++} ++ ++/** ++ * sg_init_table - Initialize SG table ++ * @sgl: The SG table ++ * @nents: Number of entries in table ++ * ++ * Notes: ++ * If this is part of a chained sg table, sg_mark_end() should be ++ * used only on the last table part. ++ * ++ **/ ++static inline void sg_init_table(struct scatterlist *sgl, unsigned int nents) ++{ ++ memset(sgl, 0, sizeof(*sgl) * nents); ++} ++ ++/** ++ * usb_endpoint_num - get the endpoint's number ++ * @epd: endpoint to be checked ++ * ++ * Returns @epd's number: 0 to 15. ++ */ ++static inline int usb_endpoint_num(const struct usb_endpoint_descriptor *epd) ++{ ++ return epd->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; ++} ++ ++#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)) */ ++ ++#endif /* LINUX_26_24_COMPAT_H */ diff --cc compat/include/linux/compat-2.6.25.h index 000000000000,000000000000..dd986f5c6013 new file mode 100644 --- /dev/null +++ b/compat/include/linux/compat-2.6.25.h @@@ -1,0 -1,0 +1,361 @@@ ++#ifndef LINUX_26_25_COMPAT_H ++#define LINUX_26_25_COMPAT_H ++ ++#include ++ ++/* Compat work for 2.6.24 */ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25)) ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#define __inet_lookup_established __inet_lookup_established_old ++#include ++#undef __inet_lookup_established ++#include ++ ++struct sg_table { ++ struct scatterlist *sgl; /* the list */ ++ unsigned int nents; /* number of mapped entries */ ++ unsigned int orig_nents; /* original size of list */ ++}; ++ ++#define sg_alloc_fn LINUX_BACKPORT(sg_alloc_fn) ++typedef struct scatterlist *(sg_alloc_fn)(unsigned int, gfp_t); ++ ++#define sg_free_fn LINUX_BACKPORT(sg_free_fn) ++typedef void (sg_free_fn)(struct scatterlist *, unsigned int); ++ ++#define __sg_free_table LINUX_BACKPORT(__sg_free_table) ++void __sg_free_table(struct sg_table *table, unsigned int max_ents, ++ sg_free_fn *free_fn); ++#define sg_free_table LINUX_BACKPORT(sg_free_table) ++void sg_free_table(struct sg_table *); ++#define __sg_alloc_table LINUX_BACKPORT(__sg_alloc_table) ++int __sg_alloc_table(struct sg_table *table, unsigned int nents, ++ unsigned int max_ents, gfp_t gfp_mask, ++ sg_alloc_fn *alloc_fn); ++#define sg_alloc_table LINUX_BACKPORT(sg_alloc_table) ++int sg_alloc_table(struct sg_table *table, unsigned int nents, gfp_t gfp_mask); ++ ++/* ++ * Maximum number of entries that will be allocated in one piece, if ++ * a list larger than this is required then chaining will be utilized. ++ */ ++#define SG_MAX_SINGLE_ALLOC (PAGE_SIZE / sizeof(struct scatterlist)) ++ ++ ++/* ++ * Sockets in TCP_CLOSE state are _always_ taken out of the hash, so we need ++ * not check it for lookups anymore, thanks Alexey. -DaveM ++ * ++ * Local BH must be disabled here. ++ */ ++static inline struct sock * ++ __inet_lookup_established(struct inet_hashinfo *hashinfo, ++ const __be32 saddr, const __be16 sport, ++ const __be32 daddr, const u16 hnum, ++ const int dif) ++{ ++ INET_ADDR_COOKIE(acookie, saddr, daddr) ++ const __portpair ports = INET_COMBINED_PORTS(sport, hnum); ++ struct sock *sk; ++ /* Optimize here for direct hit, only listening connections can ++ * have wildcards anyways. ++ */ ++ unsigned int hash = inet_ehashfn(daddr, hnum, saddr, sport); ++ struct inet_ehash_bucket *head = inet_ehash_bucket(hashinfo, hash); ++ rwlock_t *lock = inet_ehash_lockp(hashinfo, hash); ++ ++ prefetch(head->chain.first); ++ read_lock(lock); ++ sk_for_each(sk, &head->chain) { ++ if (INET_MATCH(sk, hash, acookie, saddr, daddr, ports, dif)) ++ goto hit; /* You sunk my battleship! */ ++ } ++ ++ /* Must check for a TIME_WAIT'er before going to listener hash. */ ++ sk_for_each(sk, &head->twchain) { ++ if (INET_TW_MATCH(sk, hash, acookie, saddr, daddr, ports, dif)) ++ goto hit; ++ } ++ sk = NULL; ++out: ++ read_unlock(lock); ++ return sk; ++hit: ++ sock_hold(sk); ++ goto out; ++} ++ ++/* Backports b718989da7 */ ++#define pci_enable_device_mem LINUX_BACKPORT(pci_enable_device_mem) ++int __must_check pci_enable_device_mem(struct pci_dev *dev); ++ ++/* ++ * Backports 312b1485fb509c9bc32eda28ad29537896658cb8 ++ * Author: Sam Ravnborg ++ * Date: Mon Jan 28 20:21:15 2008 +0100 ++ * ++ * Introduce new section reference annotations tags: __ref, __refdata, __refconst ++ */ ++#define __ref __init_refok ++#define __refdata __initdata_refok ++ ++/* ++ * backports 2658fa803111dae1353602e7f586de8e537803e2 ++ */ ++ ++static inline bool ipv4_is_loopback(__be32 addr) ++{ ++ return (addr & htonl(0xff000000)) == htonl(0x7f000000); ++} ++ ++static inline bool ipv4_is_multicast(__be32 addr) ++{ ++ return (addr & htonl(0xf0000000)) == htonl(0xe0000000); ++} ++ ++static inline bool ipv4_is_local_multicast(__be32 addr) ++{ ++ return (addr & htonl(0xffffff00)) == htonl(0xe0000000); ++} ++ ++static inline bool ipv4_is_lbcast(__be32 addr) ++{ ++ /* limited broadcast */ ++ return addr == htonl(INADDR_BROADCAST); ++} ++ ++static inline bool ipv4_is_zeronet(__be32 addr) ++{ ++ return (addr & htonl(0xff000000)) == htonl(0x00000000); ++} ++ ++/* Special-Use IPv4 Addresses (RFC3330) */ ++ ++static inline bool ipv4_is_private_10(__be32 addr) ++{ ++ return (addr & htonl(0xff000000)) == htonl(0x0a000000); ++} ++ ++static inline bool ipv4_is_private_172(__be32 addr) ++{ ++ return (addr & htonl(0xfff00000)) == htonl(0xac100000); ++} ++ ++static inline bool ipv4_is_private_192(__be32 addr) ++{ ++ return (addr & htonl(0xffff0000)) == htonl(0xc0a80000); ++} ++ ++static inline bool ipv4_is_linklocal_169(__be32 addr) ++{ ++ return (addr & htonl(0xffff0000)) == htonl(0xa9fe0000); ++} ++ ++static inline bool ipv4_is_anycast_6to4(__be32 addr) ++{ ++ return (addr & htonl(0xffffff00)) == htonl(0xc0586300); ++} ++ ++static inline bool ipv4_is_test_192(__be32 addr) ++{ ++ return (addr & htonl(0xffffff00)) == htonl(0xc0000200); ++} ++ ++static inline bool ipv4_is_test_198(__be32 addr) ++{ ++ return (addr & htonl(0xfffe0000)) == htonl(0xc6120000); ++} ++ ++/* ++ * phys_addr_t was added as a generic arch typedef on 2.6.28, ++ * that backport is dealt with in compat-2.6.28.h ++ */ ++#if defined(CONFIG_X86) || defined(CONFIG_X86_64) ++ ++#if defined(CONFIG_64BIT) || defined(CONFIG_X86_PAE) || defined(CONFIG_PHYS_64BIT) ++typedef u64 phys_addr_t; ++#else ++typedef u32 phys_addr_t; ++#endif ++ ++#endif /* x86 */ ++ ++/* The macro below uses a const upstream, this differs */ ++ ++/** ++ * DEFINE_PCI_DEVICE_TABLE - macro used to describe a pci device table ++ * @_table: device table name ++ * ++ * This macro is used to create a struct pci_device_id array (a device table) ++ * in a generic manner. ++ */ ++#define DEFINE_PCI_DEVICE_TABLE(_table) \ ++ const struct pci_device_id _table[] __devinitdata ++ ++/* ++ * Backport work for QoS dependencies (kernel/pm_qos_params.c) ++ * pm-qos stuff written by mark gross mgross@linux.intel.com. ++ * ++ * ipw2100 now makes use of: ++ * ++ * pm_qos_add_requirement(), ++ * pm_qos_update_requirement() and ++ * pm_qos_remove_requirement() from it ++ * ++ * mac80211 uses the network latency to determine if to enable or not ++ * dynamic PS. mac80211 also and registers a notifier for when ++ * the latency changes. Since older kernels do no thave pm-qos stuff ++ * we just implement it completley here and register it upon cfg80211 ++ * init. I haven't tested ipw2100 on 2.6.24 though. ++ * ++ * This pm-qos implementation is copied verbatim from the kernel ++ * written by mark gross mgross@linux.intel.com. You don't have ++ * to do anythinig to use pm-qos except use the same exported ++ * routines as used in newer kernels. The backport_pm_qos_power_init() ++ * defned below is used by the compat module to initialize pm-qos. ++ */ ++int backport_pm_qos_power_init(void); ++int backport_pm_qos_power_deinit(void); ++ ++/* ++ * 2.6.25 adds PM_EVENT_HIBERNATE as well here but ++ * we don't have this on <= 2.6.23) ++ */ ++#ifndef PM_EVENT_SLEEP /* some distribution have mucked with their own headers to add this.. */ ++#define PM_EVENT_SLEEP (PM_EVENT_SUSPEND) ++#endif ++ ++/* Although we don't care about wimax this is needed for rfkill input stuff */ ++#define KEY_WIMAX 246 ++ ++/* Although pm_qos stuff is not implemented on <= 2.6.24 lets keep the define */ ++#define PM_QOS_DEFAULT_VALUE -1 ++ ++#define __WARN(foo) dump_stack() ++ ++#define dev_emerg(dev, format, arg...) \ ++ dev_printk(KERN_EMERG , dev , format , ## arg) ++#define dev_alert(dev, format, arg...) \ ++ dev_printk(KERN_ALERT , dev , format , ## arg) ++#define dev_crit(dev, format, arg...) \ ++ dev_printk(KERN_CRIT , dev , format , ## arg) ++ ++#define __dev_addr_sync LINUX_BACKPORT(__dev_addr_sync) ++extern int __dev_addr_sync(struct dev_addr_list **to, int *to_count, struct dev_addr_list **from, int *from_count); ++#define __dev_addr_unsync LINUX_BACKPORT(__dev_addr_unsync) ++extern void __dev_addr_unsync(struct dev_addr_list **to, int *to_count, struct dev_addr_list **from, int *from_count); ++ ++#define seq_file_net &init_net; ++ ++enum nf_inet_hooks { ++ NF_INET_PRE_ROUTING = 0, ++ NF_INET_LOCAL_IN = 1, ++ NF_INET_FORWARD = 2, ++ NF_INET_LOCAL_OUT = 3, ++ NF_INET_POST_ROUTING = 4, ++ NF_INET_NUMHOOKS = 5 ++}; ++ ++/* The patch: ++ * commit 8b5f6883683c91ad7e1af32b7ceeb604d68e2865 ++ * Author: Marcin Slusarz ++ * Date: Fri Feb 8 04:20:12 2008 -0800 ++ * ++ * byteorder: move le32_add_cpu & friends from OCFS2 to core ++ * ++ * moves le*_add_cpu and be*_add_cpu functions from OCFS2 to core ++ * header (1st) and converted some existing code to it. We port ++ * it here as later kernels will most likely use it. ++ */ ++static inline void le16_add_cpu(__le16 *var, u16 val) ++{ ++ *var = cpu_to_le16(le16_to_cpu(*var) + val); ++} ++ ++static inline void le32_add_cpu(__le32 *var, u32 val) ++{ ++ *var = cpu_to_le32(le32_to_cpu(*var) + val); ++} ++ ++static inline void le64_add_cpu(__le64 *var, u64 val) ++{ ++ *var = cpu_to_le64(le64_to_cpu(*var) + val); ++} ++ ++static inline void be16_add_cpu(__be16 *var, u16 val) ++{ ++ u16 v = be16_to_cpu(*var); ++ *var = cpu_to_be16(v + val); ++} ++ ++static inline void be32_add_cpu(__be32 *var, u32 val) ++{ ++ u32 v = be32_to_cpu(*var); ++ *var = cpu_to_be32(v + val); ++} ++ ++static inline void be64_add_cpu(__be64 *var, u64 val) ++{ ++ u64 v = be64_to_cpu(*var); ++ *var = cpu_to_be64(v + val); ++} ++ ++/* 2.6.25 changes hwrng_unregister()'s behaviour by supporting ++ * suspend of its parent device (the misc device, which is itself the ++ * hardware random number generator). It does this by passing a parameter to ++ * unregister_miscdev() which is not supported in older kernels. The suspend ++ * parameter allows us to enable access to the device's hardware ++ * number generator during suspend. As far as wireless is concerned this means ++ * if a driver goes to suspend it you won't have the HNR available in ++ * older kernels. */ ++static inline void __hwrng_unregister(struct hwrng *rng, bool suspended) ++{ ++ hwrng_unregister(rng); ++} ++ ++static inline void led_classdev_unregister_suspended(struct led_classdev *lcd) ++{ ++ led_classdev_unregister(lcd); ++} ++ ++/** ++ * The following things are out of ./include/linux/kernel.h ++ * The new iwlwifi driver is using them. ++ */ ++#define strict_strtoul LINUX_BACKPORT(strict_strtoul) ++extern int strict_strtoul(const char *, unsigned int, unsigned long *); ++#define strict_strtol LINUX_BACKPORT(strict_strtol) ++extern int strict_strtol(const char *, unsigned int, long *); ++ ++#else ++/* ++ * Kernels >= 2.6.25 have pm-qos and its initialized as part of ++ * the bootup process ++ */ ++static inline int backport_pm_qos_power_init(void) ++{ ++ return 0; ++} ++ ++static inline int backport_pm_qos_power_deinit(void) ++{ ++ return 0; ++} ++#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25)) */ ++ ++#endif /* LINUX_26_25_COMPAT_H */ diff --cc compat/include/linux/compat-2.6.26.h index 000000000000,000000000000..b8d9dc645377 new file mode 100644 --- /dev/null +++ b/compat/include/linux/compat-2.6.26.h @@@ -1,0 -1,0 +1,456 @@@ ++#ifndef LINUX_26_26_COMPAT_H ++#define LINUX_26_26_COMPAT_H ++ ++#include ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26)) ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)) ++#include ++#endif ++#include ++#include ++#include ++ ++/* These jiffie helpers added as of 2.6.26 */ ++ ++/* ++ * These four macros compare jiffies and 'a' for convenience. ++ */ ++ ++/* time_is_before_jiffies(a) return true if a is before jiffies */ ++#define time_is_before_jiffies(a) time_after(jiffies, a) ++ ++/* time_is_after_jiffies(a) return true if a is after jiffies */ ++#define time_is_after_jiffies(a) time_before(jiffies, a) ++ ++/* time_is_before_eq_jiffies(a) return true if a is before or equal to jiffies*/ ++#define time_is_before_eq_jiffies(a) time_after_eq(jiffies, a) ++ ++/* time_is_after_eq_jiffies(a) return true if a is after or equal to jiffies*/ ++#define time_is_after_eq_jiffies(a) time_before_eq(jiffies, a) ++ ++/* This comes from include/linux/input.h */ ++#define SW_RFKILL_ALL 0x03 /* rfkill master switch, type "any" ++ set = radio enabled */ ++ ++/* From kernel.h */ ++#define USHORT_MAX ((u16)(~0U)) ++#define SHORT_MAX ((s16)(USHORT_MAX>>1)) ++#define SHORT_MIN (-SHORT_MAX - 1) ++ ++#define dev_set_name LINUX_BACKPORT(dev_set_name) ++extern int dev_set_name(struct device *dev, const char *name, ...) ++ __attribute__((format(printf, 2, 3))); ++ ++/** ++ * clamp - return a value clamped to a given range with strict typechecking ++ * @val: current value ++ * @min: minimum allowable value ++ * @max: maximum allowable value ++ * ++ * This macro does strict typechecking of min/max to make sure they are of the ++ * same type as val. See the unnecessary pointer comparisons. ++ */ ++#define clamp(val, min, max) ({ \ ++ typeof(val) __val = (val); \ ++ typeof(min) __min = (min); \ ++ typeof(max) __max = (max); \ ++ (void) (&__val == &__min); \ ++ (void) (&__val == &__max); \ ++ __val = __val < __min ? __min: __val; \ ++ __val > __max ? __max: __val; }) ++ ++/** ++ * clamp_t - return a value clamped to a given range using a given type ++ * @type: the type of variable to use ++ * @val: current value ++ * @min: minimum allowable value ++ * @max: maximum allowable value ++ * ++ * This macro does no typechecking and uses temporary variables of type ++ * 'type' to make all the comparisons. ++ */ ++#define clamp_t(type, val, min, max) ({ \ ++ type __val = (val); \ ++ type __min = (min); \ ++ type __max = (max); \ ++ __val = __val < __min ? __min: __val; \ ++ __val > __max ? __max: __val; }) ++ ++ ++/* from include/linux/device.h */ ++/* device_create_drvdata() is new */ ++extern struct device *device_create_drvdata(struct class *cls, ++ struct device *parent, ++ dev_t devt, ++ void *drvdata, ++ const char *fmt, ...) ++__attribute__((format(printf, 5, 6))); ++ ++/* This is from include/linux/list.h */ ++ ++/** ++ * list_is_singular - tests whether a list has just one entry. ++ * @head: the list to test. ++ */ ++static inline int list_is_singular(const struct list_head *head) ++{ ++ return !list_empty(head) && (head->next == head->prev); ++} ++ ++/* This is from include/linux/device.h, which was added as of 2.6.26 */ ++static inline const char *dev_name(struct device *dev) ++{ ++ /* will be changed into kobject_name(&dev->kobj) in the near future */ ++ return dev->bus_id; ++} ++ ++/* This is from include/linux/kernel.h, which was added as of 2.6.26 */ ++ ++/** ++ * clamp_val - return a value clamped to a given range using val's type ++ * @val: current value ++ * @min: minimum allowable value ++ * @max: maximum allowable value ++ * ++ * This macro does no typechecking and uses temporary variables of whatever ++ * type the input argument 'val' is. This is useful when val is an unsigned ++ * type and min and max are literals that will otherwise be assigned a signed ++ * integer type. ++ */ ++ ++#define clamp_val(val, min, max) ({ \ ++ typeof(val) __val = (val); \ ++ typeof(val) __min = (min); \ ++ typeof(val) __max = (max); \ ++ __val = __val < __min ? __min: __val; \ ++ __val > __max ? __max: __val; }) ++ ++/* This comes from include/net/net_namespace.h */ ++ ++#ifdef CONFIG_NET_NS ++static inline ++int net_eq(const struct net *net1, const struct net *net2) ++{ ++ return net1 == net2; ++} ++#else ++static inline ++int net_eq(const struct net *net1, const struct net *net2) ++{ ++ return 1; ++} ++#endif ++ ++static inline ++void dev_net_set(struct net_device *dev, struct net *net) ++{ ++#ifdef CONFIG_NET_NS ++ release_net(dev->nd_net); ++ dev->nd_net = hold_net(net); ++#endif ++} ++ ++static inline ++struct net *sock_net(const struct sock *sk) ++{ ++#ifdef CONFIG_NET_NS ++ return sk->sk_net; ++#else ++ return &init_net; ++#endif ++} ++ ++/* This comes from include/linux/netdevice.h */ ++ ++/* ++ * Net namespace inlines ++ */ ++static inline ++struct net *dev_net(const struct net_device *dev) ++{ ++#ifdef CONFIG_NET_NS ++ /* ++ * compat-wirelss backport note: ++ * For older kernels we may just need to always return init_net, ++ * not sure when we added dev->nd_net. ++ */ ++ return dev->nd_net; ++#else ++ return &init_net; ++#endif ++} ++ ++ ++/* ++ * 2.6.26 added its own unaligned API which the ++ * new drivers can use. Lets port it here by including it in older ++ * kernels and also deal with the architecture handling here. ++ */ ++ ++#ifdef CONFIG_ALPHA ++ ++#include ++#include ++#include ++ ++#endif /* alpha */ ++#ifdef CONFIG_ARM ++ ++/* arm */ ++#include ++#include ++#include ++ ++#endif /* arm */ ++#ifdef CONFIG_AVR32 ++ ++/* ++ * AVR32 can handle some unaligned accesses, depending on the ++ * implementation. The AVR32 AP implementation can handle unaligned ++ * words, but halfwords must be halfword-aligned, and doublewords must ++ * be word-aligned. ++ * ++ * However, swapped word loads must be word-aligned so we can't ++ * optimize word loads in general. ++ */ ++ ++#include ++#include ++#include ++ ++#endif ++#ifdef CONFIG_BLACKFIN ++ ++#include ++#include ++#include ++ ++#endif /* blackfin */ ++#ifdef CONFIG_CRIS ++ ++/* ++ * CRIS can do unaligned accesses itself. ++ */ ++#include ++#include ++ ++#endif /* cris */ ++#ifdef CONFIG_FRV ++ ++#include ++#include ++#include ++ ++#endif /* frv */ ++#ifdef CONFIG_H8300 ++ ++#include ++#include ++#include ++ ++#endif /* h8300 */ ++#ifdef CONFIG_IA64 ++ ++#include ++#include ++#include ++ ++#endif /* ia64 */ ++#ifdef CONFIG_M32R ++ ++#if defined(__LITTLE_ENDIAN__) ++# include ++# include ++# include ++#else ++# include ++# include ++# include ++#endif ++ ++#endif /* m32r */ ++#ifdef CONFIG_M68K /* this handles both m68k and m68knommu */ ++ ++#ifdef CONFIG_COLDFIRE ++#include ++#include ++#include ++#else ++ ++/* ++ * The m68k can do unaligned accesses itself. ++ */ ++#include ++#include ++#endif ++ ++#endif /* m68k and m68knommu */ ++#ifdef CONFIG_MIPS ++ ++#if defined(__MIPSEB__) ++# include ++# include ++# include ++# define get_unaligned __get_unaligned_be ++# define put_unaligned __put_unaligned_be ++#elif defined(__MIPSEL__) ++# include ++# include ++# include ++#endif ++ ++#endif /* mips */ ++#ifdef CONFIG_MN10300 ++ ++#include ++#include ++ ++#endif /* mn10300 */ ++#ifdef CONFIG_PARISC ++ ++#include ++#include ++#include ++ ++#endif /* parisc */ ++#ifdef CONFIG_PPC ++/* ++ * The PowerPC can do unaligned accesses itself in big endian mode. ++ */ ++#include ++#include ++ ++#endif /* ppc */ ++#ifdef CONFIG_S390 ++ ++/* ++ * The S390 can do unaligned accesses itself. ++ */ ++#include ++#include ++ ++#endif /* s390 */ ++#ifdef CONFIG_SUPERH ++ ++/* SH can't handle unaligned accesses. */ ++#ifdef __LITTLE_ENDIAN__ ++# include ++# include ++# include ++#else ++# include ++# include ++# include ++#endif ++ ++#endif /* sh - SUPERH */ ++#ifdef CONFIG_SPARC ++ ++/* sparc and sparc64 */ ++#include ++#include ++#include ++ ++#endif /* sparc */ ++#ifdef CONFIG_UML ++ ++#include "asm/arch/unaligned.h" ++ ++#endif /* um - uml */ ++#ifdef CONFIG_V850 ++ ++#include ++#include ++#include ++ ++#endif /* v850 */ ++#ifdef CONFIG_X86 ++/* ++ * The x86 can do unaligned accesses itself. ++ */ ++#include ++#include ++ ++#endif /* x86 */ ++#ifdef CONFIG_XTENSA ++ ++#ifdef __XTENSA_EL__ ++# include ++# include ++# include ++#elif defined(__XTENSA_EB__) ++# include ++# include ++# include ++#else ++# error processor byte order undefined! ++#endif ++ ++#endif /* xtensa */ ++ ++#define PCIE_LINK_STATE_L0S 1 ++#define PCIE_LINK_STATE_L1 2 ++#define PCIE_LINK_STATE_CLKPM 4 ++ ++static inline void pci_disable_link_state(struct pci_dev *pdev, int state) ++{ ++} ++/* source: include/linux/pci-aspm.h */ ++ ++ ++#if BITS_PER_LONG == 64 ++ ++/** ++ * div_u64_rem - unsigned 64bit divide with 32bit divisor with remainder ++ * ++ * This is commonly provided by 32bit archs to provide an optimized 64bit ++ * divide. ++ */ ++static inline u64 div_u64_rem(u64 dividend, u32 divisor, u32 *remainder) ++{ ++ *remainder = dividend % divisor; ++ return dividend / divisor; ++} ++ ++#elif BITS_PER_LONG == 32 ++ ++#ifndef div_u64_rem ++static inline u64 div_u64_rem(u64 dividend, u32 divisor, u32 *remainder) ++{ ++ *remainder = do_div(dividend, divisor); ++ return dividend; ++} ++#endif ++ ++#endif /* BITS_PER_LONG */ ++ ++/** ++ * div_u64 - unsigned 64bit divide with 32bit divisor ++ * ++ * This is the most common 64bit divide and should be used if possible, ++ * as many 32bit archs can optimize this variant better than a full 64bit ++ * divide. ++ */ ++#ifndef div_u64 ++static inline u64 div_u64(u64 dividend, u32 divisor) ++{ ++ u32 remainder; ++ return div_u64_rem(dividend, divisor, &remainder); ++} ++#endif ++/* source: include/math64.h */ ++ ++#define hex_asc_lo(x) hex_asc((x) & 0x0f) ++#define hex_asc_hi(x) hex_asc(((x) & 0xf0) >> 4) ++ ++#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26)) */ ++ ++#endif /* LINUX_26_26_COMPAT_H */ diff --cc compat/include/linux/compat-2.6.27.h index 000000000000,000000000000..b71a3b57a202 new file mode 100644 --- /dev/null +++ b/compat/include/linux/compat-2.6.27.h @@@ -1,0 -1,0 +1,317 @@@ ++#ifndef LINUX_26_27_COMPAT_H ++#define LINUX_26_27_COMPAT_H ++ ++#include ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)) ++ ++#include ++#include ++#include ++#include ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)) ++#include ++#include ++#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24) */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static inline struct net_device *qdisc_dev(const struct Qdisc *qdisc) ++{ ++ return qdisc->dev; ++} ++ ++/* ++ * Backports 378a2f09 and c27f339a ++ * This may need a bit more work. ++ */ ++enum net_xmit_qdisc_t { ++ __NET_XMIT_STOLEN = 0x00010000, ++ __NET_XMIT_BYPASS = 0x00020000, ++}; ++ ++struct qdisc_skb_cb { ++ unsigned int pkt_len; ++ char data[]; ++}; ++ ++static inline struct qdisc_skb_cb *qdisc_skb_cb(struct sk_buff *skb) ++{ ++ return (struct qdisc_skb_cb *)skb->cb; ++} ++ ++static inline unsigned int qdisc_pkt_len(struct sk_buff *skb) ++{ ++ return qdisc_skb_cb(skb)->pkt_len; ++} ++ ++#define PCI_PM_CAP_PME_SHIFT 11 ++ ++/* I can't find a more suitable replacement... */ ++#define flush_work(work) cancel_work_sync(work) ++ ++struct builtin_fw { ++ char *name; ++ void *data; ++ unsigned long size; ++}; ++ ++/* ++ * On older kernels we do not have net_device Multi Queue support, but ++ * since we no longer use MQ on mac80211 we can simply use the 0 queue. ++ * Note that if other fullmac drivers make use of this they then need ++ * to be backported somehow or deal with just 1 queueue from MQ. ++ */ ++static inline void netif_tx_wake_all_queues(struct net_device *dev) ++{ ++ netif_wake_queue(dev); ++} ++static inline void netif_tx_start_all_queues(struct net_device *dev) ++{ ++ netif_start_queue(dev); ++} ++static inline void netif_tx_stop_all_queues(struct net_device *dev) ++{ ++ netif_stop_queue(dev); ++} ++ ++/* Are all TX queues of the device empty? */ ++static inline bool qdisc_all_tx_empty(const struct net_device *dev) ++{ ++ return skb_queue_empty(&dev->qdisc->q); ++} ++ ++#define pci_pme_capable LINUX_BACKPORT(pci_pme_capable) ++bool pci_pme_capable(struct pci_dev *dev, pci_power_t state); ++ ++/* ++ * The net_device has a spin_lock on newer kernels, on older kernels we're out of luck ++ */ ++#define netif_addr_lock_bh(dev) ++#define netif_addr_unlock_bh(dev) ++ ++/* ++ * To port this properly we'd have to port warn_slowpath_null(), ++ * which I'm lazy to do so just do a regular print for now. If you ++ * want to port this read kernel/panic.c ++ */ ++#define __WARN_printf(arg...) do { printk(arg); __WARN(); } while (0) ++ ++/* This is ported directly as-is on newer kernels */ ++#ifndef WARN ++#define WARN(condition, format...) ({ \ ++ int __ret_warn_on = !!(condition); \ ++ if (unlikely(__ret_warn_on)) \ ++ __WARN_printf(format); \ ++ unlikely(__ret_warn_on); \ ++}) ++#endif ++ ++/* On 2.6.27 a second argument was added, on older kernels we ignore it */ ++#define dma_mapping_error(pdev, dma_addr) dma_mapping_error(dma_addr) ++#define pci_dma_mapping_error(pdev, dma_addr) dma_mapping_error(pdev, dma_addr) ++ ++/* This is from include/linux/ieee80211.h */ ++#define IEEE80211_HT_CAP_DSSSCCK40 0x1000 ++ ++/* New link list changes added as of 2.6.27, needed for ath9k */ ++ ++static inline void __list_cut_position(struct list_head *list, ++ struct list_head *head, struct list_head *entry) ++{ ++ struct list_head *new_first = entry->next; ++ list->next = head->next; ++ list->next->prev = list; ++ list->prev = entry; ++ entry->next = list; ++ head->next = new_first; ++ new_first->prev = head; ++} ++ ++/** ++ * list_cut_position - cut a list into two ++ * @list: a new list to add all removed entries ++ * @head: a list with entries ++ * @entry: an entry within head, could be the head itself ++ * and if so we won't cut the list ++ * ++ * This helper moves the initial part of @head, up to and ++ * including @entry, from @head to @list. You should ++ * pass on @entry an element you know is on @head. @list ++ * should be an empty list or a list you do not care about ++ * losing its data. ++ * ++ */ ++static inline void list_cut_position(struct list_head *list, ++ struct list_head *head, struct list_head *entry) ++{ ++ if (list_empty(head)) ++ return; ++ if (list_is_singular(head) && ++ (head->next != entry && head != entry)) ++ return; ++ if (entry == head) ++ INIT_LIST_HEAD(list); ++ else ++ __list_cut_position(list, head, entry); ++} ++ ++ ++/* __list_splice as re-implemented on 2.6.27, we backport it */ ++static inline void __compat_list_splice_new_27(const struct list_head *list, ++ struct list_head *prev, ++ struct list_head *next) ++{ ++ struct list_head *first = list->next; ++ struct list_head *last = list->prev; ++ ++ first->prev = prev; ++ prev->next = first; ++ ++ last->next = next; ++ next->prev = last; ++} ++ ++/** ++ * list_splice_tail - join two lists, each list being a queue ++ * @list: the new list to add. ++ * @head: the place to add it in the first list. ++ */ ++static inline void list_splice_tail(struct list_head *list, ++ struct list_head *head) ++{ ++ if (!list_empty(list)) ++ __compat_list_splice_new_27(list, head->prev, head); ++} ++ ++/** ++ * list_splice_tail_init - join two lists and reinitialise the emptied list ++ * @list: the new list to add. ++ * @head: the place to add it in the first list. ++ * ++ * Each of the lists is a queue. ++ * The list at @list is reinitialised ++ */ ++static inline void list_splice_tail_init(struct list_head *list, ++ struct list_head *head) ++{ ++ if (!list_empty(list)) { ++ __compat_list_splice_new_27(list, head->prev, head); ++ INIT_LIST_HEAD(list); ++ } ++} ++ ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)) ++#define mmc_align_data_size LINUX_BACKPORT(mmc_align_data_size) ++extern unsigned int mmc_align_data_size(struct mmc_card *, unsigned int); ++#define sdio_align_size LINUX_BACKPORT(sdio_align_size) ++extern unsigned int sdio_align_size(struct sdio_func *func, unsigned int sz); ++#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24) */ ++ ++#define iwe_stream_add_value(info, event, value, ends, iwe, event_len) iwe_stream_add_value(event, value, ends, iwe, event_len) ++#define iwe_stream_add_point(info, stream, ends, iwe, extra) iwe_stream_add_point(stream, ends, iwe, extra) ++#define iwe_stream_add_event(info, stream, ends, iwe, event_len) iwe_stream_add_event(stream, ends, iwe, event_len) ++ ++/* Flags available in struct iw_request_info */ ++#define IW_REQUEST_FLAG_COMPAT 0x0001 /* Compat ioctl call */ ++ ++static inline int iwe_stream_lcp_len(struct iw_request_info *info) ++{ ++#ifdef CONFIG_COMPAT ++ if (info->flags & IW_REQUEST_FLAG_COMPAT) ++ return IW_EV_COMPAT_LCP_LEN; ++#endif ++ return IW_EV_LCP_LEN; ++} ++ ++#ifdef CONFIG_ARM ++ ++/* ++ * The caller asks to handle a range between offset and offset + size, ++ * but we process a larger range from 0 to offset + size due to lack of ++ * offset support. ++ */ ++ ++static inline void dma_sync_single_range_for_cpu(struct device *dev, ++ dma_addr_t handle, unsigned long offset, size_t size, ++ enum dma_data_direction dir) ++{ ++ dma_sync_single_for_cpu(dev, handle, offset + size, dir); ++} ++ ++static inline void dma_sync_single_range_for_device(struct device *dev, ++ dma_addr_t handle, unsigned long offset, size_t size, ++ enum dma_data_direction dir) ++{ ++ dma_sync_single_for_device(dev, handle, offset + size, dir); ++} ++ ++#endif /* arm */ ++ ++#define debugfs_remove_recursive LINUX_BACKPORT(debugfs_remove_recursive) ++ ++#if defined(CONFIG_DEBUG_FS) ++void debugfs_remove_recursive(struct dentry *dentry); ++#else ++static inline void debugfs_remove_recursive(struct dentry *dentry) ++{ } ++#endif ++ ++#define device_create(cls, parent, devt, drvdata, fmt, ...) \ ++({ \ ++ struct device *_dev; \ ++ _dev = (device_create)(cls, parent, devt, fmt, __VA_ARGS__); \ ++ dev_set_drvdata(_dev, drvdata); \ ++ _dev; \ ++}) ++ ++#define dev_name(dev) dev_name((struct device *)dev) ++ ++static inline void ethtool_cmd_speed_set(struct ethtool_cmd *ep, ++ __u32 speed) ++{ ++ ep->speed = (__u16)speed; ++} ++ ++static inline __u32 ethtool_cmd_speed(const struct ethtool_cmd *ep) ++{ ++ return ep->speed; ++} ++ ++/** ++ * lower_32_bits - return bits 0-31 of a number ++ * @n: the number we're accessing ++ */ ++#define lower_32_bits(n) ((u32)(n)) ++ ++#define netif_wake_subqueue netif_start_subqueue ++ ++/* Backport of: ++ * ++ * commit 3295f0ef9ff048a4619ede597ad9ec9cab725654 ++ * Author: Ingo Molnar ++ * Date: Mon Aug 11 10:30:30 2008 +0200 ++ * ++ * lockdep: rename map_[acquire|release]() => lock_map_[acquire|release]() ++ */ ++#ifdef CONFIG_DEBUG_LOCK_ALLOC ++# ifdef CONFIG_PROVE_LOCKING ++# define lock_map_acquire(l) lock_acquire(l, 0, 0, 0, 2, NULL, _THIS_IP_) ++# else ++# define lock_map_acquire(l) lock_acquire(l, 0, 0, 0, 1, NULL, _THIS_IP_) ++# endif ++# define lock_map_release(l) lock_release(l, 1, _THIS_IP_) ++#else ++# define lock_map_acquire(l) do { } while (0) ++# define lock_map_release(l) do { } while (0) ++#endif ++ ++#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)) */ ++ ++#endif /* LINUX_26_27_COMPAT_H */ diff --cc compat/include/linux/compat-2.6.28.h index 000000000000,000000000000..3b5f3ea7141c new file mode 100644 --- /dev/null +++ b/compat/include/linux/compat-2.6.28.h @@@ -1,0 -1,0 +1,305 @@@ ++#ifndef LINUX_26_28_COMPAT_H ++#define LINUX_26_28_COMPAT_H ++ ++#include ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)) ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define HID_ANY_ID (~0) ++ ++#define HID_USB_DEVICE(ven, prod) \ ++ .bus = BUS_USB, .vendor = (ven), .product = (prod) ++#define HID_BLUETOOTH_DEVICE(ven, prod) \ ++ .bus = BUS_BLUETOOTH, .vendor = (ven), .product = (prod) ++ ++ ++struct hid_device_id { ++ __u16 bus; ++ __u32 vendor; ++ __u32 product; ++ kernel_ulong_t driver_data ++ __attribute__((aligned(sizeof(kernel_ulong_t)))); ++}; ++ ++#ifndef ETH_P_PAE ++#define ETH_P_PAE 0x888E /* Port Access Entity (IEEE 802.1X) */ ++#endif ++ ++#include ++#include ++#include ++ ++#define platform_device_register_data LINUX_BACKPORT(platform_device_register_data) ++extern struct platform_device *platform_device_register_data(struct device *, ++ const char *, int, const void *, size_t); ++ ++typedef struct cpumask { DECLARE_BITMAP(bits, NR_CPUS); } compat_cpumask_t; ++ ++#if defined(CONFIG_X86) || defined(CONFIG_X86_64) || defined(CONFIG_PPC) ++/* ++ * CONFIG_PHYS_ADDR_T_64BIT was added as new to all architectures ++ * as of 2.6.28 but x86 and ppc had it already. x86 only got phys_addr_t ++ * as of 2.6.25 but then is backported in compat-2.6.25.h ++ */ ++#else ++#if defined(CONFIG_64BIT) || defined(CONFIG_X86_PAE) || defned(CONFIG_PPC64) || defined(CONFIG_PHYS_64BIT) ++#define CONFIG_PHYS_ADDR_T_64BIT 1 ++typedef u64 phys_addr_t; ++#else ++typedef u32 phys_addr_t; ++#endif ++ ++#endif /* non x86 and ppc */ ++ ++#ifndef WARN_ONCE ++#define WARN_ONCE(condition, format...) ({ \ ++ static int __warned; \ ++ int __ret_warn_once = !!(condition); \ ++ \ ++ if (unlikely(__ret_warn_once)) \ ++ if (WARN(!__warned, format)) \ ++ __warned = 1; \ ++ unlikely(__ret_warn_once); \ ++}) ++#endif /* From include/asm-generic/bug.h */ ++ ++#if defined(CONFIG_PCMCIA) || defined(CONFIG_PCMCIA_MODULE) ++ ++#include ++#include ++#include ++#ifdef pcmcia_parse_tuple ++#undef pcmcia_parse_tuple ++#define pcmcia_parse_tuple(tuple, parse) pccard_parse_tuple(tuple, parse) ++#endif ++ ++/* From : include/pcmcia/ds.h */ ++/* loop CIS entries for valid configuration */ ++#define pcmcia_loop_config LINUX_BACKPORT(pcmcia_loop_config) ++int pcmcia_loop_config(struct pcmcia_device *p_dev, ++ int (*conf_check) (struct pcmcia_device *p_dev, ++ cistpl_cftable_entry_t *cfg, ++ cistpl_cftable_entry_t *dflt, ++ unsigned int vcc, ++ void *priv_data), ++ void *priv_data); ++ ++#endif /* CONFIG_PCMCIA */ ++ ++/* USB anchors were added as of 2.6.23 */ ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23)) ++ ++#if defined(CONFIG_USB) || defined(CONFIG_USB_MODULE) ++#if 0 ++#define usb_poison_urb LINUX_BACKPORT(usb_poison_urb) ++extern void usb_poison_urb(struct urb *urb); ++#endif ++#define usb_unpoison_urb LINUX_BACKPORT(usb_unpoison_urb) ++extern void usb_unpoison_urb(struct urb *urb); ++ ++#if 0 ++#define usb_poison_anchored_urbs LINUX_BACKPORT(usb_poison_anchored_urbs) ++extern void usb_poison_anchored_urbs(struct usb_anchor *anchor); ++#endif ++ ++#define usb_anchor_empty LINUX_BACKPORT(usb_anchor_empty) ++extern int usb_anchor_empty(struct usb_anchor *anchor); ++#endif /* CONFIG_USB */ ++#endif ++ ++ ++#define pci_ioremap_bar LINUX_BACKPORT(pci_ioremap_bar) ++void __iomem *pci_ioremap_bar(struct pci_dev *pdev, int bar); ++ ++/** ++ * skb_queue_is_last - check if skb is the last entry in the queue ++ * @list: queue head ++ * @skb: buffer ++ * ++ * Returns true if @skb is the last buffer on the list. ++ */ ++static inline bool skb_queue_is_last(const struct sk_buff_head *list, ++ const struct sk_buff *skb) ++{ ++ return (skb->next == (struct sk_buff *) list); ++} ++ ++/** ++ * skb_queue_next - return the next packet in the queue ++ * @list: queue head ++ * @skb: current buffer ++ * ++ * Return the next packet in @list after @skb. It is only valid to ++ * call this if skb_queue_is_last() evaluates to false. ++ */ ++static inline struct sk_buff *skb_queue_next(const struct sk_buff_head *list, ++ const struct sk_buff *skb) ++{ ++ /* This BUG_ON may seem severe, but if we just return then we ++ * are going to dereference garbage. ++ */ ++ BUG_ON(skb_queue_is_last(list, skb)); ++ return skb->next; ++} ++ ++/** ++ * __skb_queue_head_init - initialize non-spinlock portions of sk_buff_head ++ * @list: queue to initialize ++ * ++ * This initializes only the list and queue length aspects of ++ * an sk_buff_head object. This allows to initialize the list ++ * aspects of an sk_buff_head without reinitializing things like ++ * the spinlock. It can also be used for on-stack sk_buff_head ++ * objects where the spinlock is known to not be used. ++ */ ++static inline void __skb_queue_head_init(struct sk_buff_head *list) ++{ ++ list->prev = list->next = (struct sk_buff *)list; ++ list->qlen = 0; ++} ++ ++static inline void __skb_queue_splice(const struct sk_buff_head *list, ++ struct sk_buff *prev, ++ struct sk_buff *next) ++{ ++ struct sk_buff *first = list->next; ++ struct sk_buff *last = list->prev; ++ ++ first->prev = prev; ++ prev->next = first; ++ ++ last->next = next; ++ next->prev = last; ++} ++ ++/** ++ * skb_queue_splice - join two skb lists, this is designed for stacks ++ * @list: the new list to add ++ * @head: the place to add it in the first list ++ */ ++static inline void skb_queue_splice(const struct sk_buff_head *list, ++ struct sk_buff_head *head) ++{ ++ if (!skb_queue_empty(list)) { ++ __skb_queue_splice(list, (struct sk_buff *) head, head->next); ++ head->qlen += list->qlen; ++ } ++} ++ ++/** ++ * skb_queue_splice - join two skb lists and reinitialise the emptied list ++ * @list: the new list to add ++ * @head: the place to add it in the first list ++ * ++ * The list at @list is reinitialised ++ */ ++static inline void skb_queue_splice_init(struct sk_buff_head *list, ++ struct sk_buff_head *head) ++{ ++ if (!skb_queue_empty(list)) { ++ __skb_queue_splice(list, (struct sk_buff *) head, head->next); ++ head->qlen += list->qlen; ++ __skb_queue_head_init(list); ++ } ++} ++ ++/** ++ * skb_queue_splice_tail - join two skb lists and reinitialise the emptied list ++ * @list: the new list to add ++ * @head: the place to add it in the first list ++ * ++ * Each of the lists is a queue. ++ * The list at @list is reinitialised ++ */ ++static inline void skb_queue_splice_tail_init(struct sk_buff_head *list, ++ struct sk_buff_head *head) ++{ ++ if (!skb_queue_empty(list)) { ++ __skb_queue_splice(list, head->prev, (struct sk_buff *) head); ++ head->qlen += list->qlen; ++ __skb_queue_head_init(list); ++ } ++} /* From include/linux/skbuff.h */ ++ ++/** ++ * skb_queue_splice_tail - join two skb lists, each list being a queue ++ * @list: the new list to add ++ * @head: the place to add it in the first list ++ */ ++static inline void skb_queue_splice_tail(const struct sk_buff_head *list, ++ struct sk_buff_head *head) ++{ ++ if (!skb_queue_empty(list)) { ++ __skb_queue_splice(list, head->prev, (struct sk_buff *) head); ++ head->qlen += list->qlen; ++ } ++} ++ ++#define skb_queue_walk_from(queue, skb) \ ++ for (; skb != (struct sk_buff *)(queue); \ ++ skb = skb->next) ++ ++#ifndef DECLARE_TRACE ++ ++#define TP_PROTO(args...) args ++#define TP_ARGS(args...) args ++ ++#define DECLARE_TRACE(name, proto, args) \ ++ static inline void _do_trace_##name(struct tracepoint *tp, proto) \ ++ { } \ ++ static inline void trace_##name(proto) \ ++ { } \ ++ static inline int register_trace_##name(void (*probe)(proto)) \ ++ { \ ++ return -ENOSYS; \ ++ } \ ++ static inline int unregister_trace_##name(void (*probe)(proto)) \ ++ { \ ++ return -ENOSYS; \ ++ } ++ ++#define EXPORT_TRACEPOINT_SYMBOL_GPL(name) ++#define EXPORT_TRACEPOINT_SYMBOL(name) ++ ++ ++#endif ++ ++#define round_jiffies_up LINUX_BACKPORT(round_jiffies_up) ++unsigned long round_jiffies_up(unsigned long j); ++ ++extern void v2_6_28_skb_add_rx_frag(struct sk_buff *skb, int i, struct page *page, ++ int off, int size); ++ ++#define wake_up_interruptible_poll(x, m) \ ++ __wake_up(x, TASK_INTERRUPTIBLE, 1, (void *) (m)) ++ ++#define n_tty_ioctl_helper LINUX_BACKPORT(n_tty_ioctl_helper) ++extern int n_tty_ioctl_helper(struct tty_struct *tty, struct file *file, ++ unsigned int cmd, unsigned long arg); ++ ++#define pci_wake_from_d3 LINUX_BACKPORT(pci_wake_from_d3) ++int pci_wake_from_d3(struct pci_dev *dev, bool enable); ++ ++#define alloc_workqueue(name, flags, max_active) __create_workqueue(name, flags, max_active) ++ ++#ifndef pr_fmt ++#define pr_fmt(fmt) fmt ++#endif ++ ++#define PCI_EXP_DEVCAP2 36 /* Device Capabilities 2 */ ++#define PCI_EXP_DEVCAP2_ARI 0x20 /* Alternative Routing-ID */ ++#define PCI_EXP_DEVCTL2 40 /* Device Control 2 */ ++#define PCI_EXP_DEVCTL2_ARI 0x20 /* Alternative Routing-ID */ ++ ++#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)) */ ++ ++#endif /* LINUX_26_28_COMPAT_H */ diff --cc compat/include/linux/compat-2.6.29.h index 000000000000,000000000000..c8cf89873ab5 new file mode 100644 --- /dev/null +++ b/compat/include/linux/compat-2.6.29.h @@@ -1,0 -1,0 +1,430 @@@ ++#ifndef LINUX_26_29_COMPAT_H ++#define LINUX_26_29_COMPAT_H ++ ++#include ++#include ++#include ++ ++/* ++ * I kow this looks odd.. but 2.6.32 added the netdev_tx_t ++ * and we backport that there so inlcude that header first ++ * as we need it for the netdev ops. ++ */ ++#include ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)) ++ ++#include ++#include ++#include ++#include ++ ++#define napi_gro_receive(napi, skb) netif_receive_skb(skb) ++ ++/* backports */ ++static inline void usb_autopm_put_interface_async(struct usb_interface *intf) ++{ } ++static inline int usb_autopm_get_interface_async(struct usb_interface *intf) ++{ return 0; } ++ ++#if \ ++ defined(CONFIG_ALPHA) || defined(CONFIG_AVR32) || \ ++ defined(CONFIG_BLACKFIN) || defined(CONFIG_CRIS) || \ ++ defined(CONFIG_H8300) || defined(CONFIG_IA64) || \ ++ defined(CONFIG_M68K) || defined(CONFIG_MIPS) || \ ++ defined(CONFIG_PARISC) || defined(CONFIG_S390) || \ ++ defined(CONFIG_PPC64) || defined(CONFIG_PPC32) || \ ++ defined(CONFIG_SUPERH) || defined(CONFIG_SPARC) || \ ++ defined(CONFIG_FRV) || defined(CONFIG_X86) || \ ++ defined(CONFIG_M32R) || defined(CONFIG_M68K) || \ ++ defined(CONFIG_MN10300) || defined(CONFIG_XTENSA) || \ ++ defined(CONFIG_ARM) ++#include ++#else ++typedef struct { ++ volatile int counter; ++} atomic_t; ++ ++#ifdef CONFIG_64BIT ++typedef struct { ++ volatile long counter; ++} atomic64_t; ++#endif /* CONFIG_64BIT */ ++ ++#endif ++ ++#define PCI_EXP_LNKCTL_ES 0x0080 /* Extended Synch */ ++ ++/* ++ * Older kernels do not have struct net_device_ops but what we can ++ * do is just define the data structure and use a caller to let us ++ * set the data structure's routines onto the old netdev, essentially ++ * doing it the old way. This avoids huge deltas on our backports. ++ */ ++ ++/* ++ * This structure defines the management hooks for network devices. ++ * The following hooks can be defined; unless noted otherwise, they are ++ * optional and can be filled with a null pointer. ++ * ++ * int (*ndo_init)(struct net_device *dev); ++ * This function is called once when network device is registered. ++ * The network device can use this to any late stage initializaton ++ * or semantic validattion. It can fail with an error code which will ++ * be propogated back to register_netdev ++ * ++ * void (*ndo_uninit)(struct net_device *dev); ++ * This function is called when device is unregistered or when registration ++ * fails. It is not called if init fails. ++ * ++ * int (*ndo_open)(struct net_device *dev); ++ * This function is called when network device transistions to the up ++ * state. ++ * ++ * int (*ndo_stop)(struct net_device *dev); ++ * This function is called when network device transistions to the down ++ * state. ++ * ++ * netdev_tx_t (*ndo_start_xmit)(struct sk_buff *skb, ++ * struct net_device *dev); ++ * Called when a packet needs to be transmitted. ++ * Must return NETDEV_TX_OK , NETDEV_TX_BUSY. ++ * (can also return NETDEV_TX_LOCKED iff NETIF_F_LLTX) ++ * Required can not be NULL. ++ * ++ * u16 (*ndo_select_queue)(struct net_device *dev, struct sk_buff *skb); ++ * Called to decide which queue to when device supports multiple ++ * transmit queues. ++ * ++ * void (*ndo_change_rx_flags)(struct net_device *dev, int flags); ++ * This function is called to allow device receiver to make ++ * changes to configuration when multicast or promiscious is enabled. ++ * ++ * void (*ndo_set_rx_mode)(struct net_device *dev); ++ * This function is called device changes address list filtering. ++ * ++ * void (*ndo_set_multicast_list)(struct net_device *dev); ++ * This function is called when the multicast address list changes. ++ * ++ * int (*ndo_set_mac_address)(struct net_device *dev, void *addr); ++ * This function is called when the Media Access Control address ++ * needs to be changed. If this interface is not defined, the ++ * mac address can not be changed. ++ * ++ * int (*ndo_validate_addr)(struct net_device *dev); ++ * Test if Media Access Control address is valid for the device. ++ * ++ * int (*ndo_do_ioctl)(struct net_device *dev, struct ifreq *ifr, int cmd); ++ * Called when a user request an ioctl which can't be handled by ++ * the generic interface code. If not defined ioctl's return ++ * not supported error code. ++ * ++ * int (*ndo_set_config)(struct net_device *dev, struct ifmap *map); ++ * Used to set network devices bus interface parameters. This interface ++ * is retained for legacy reason, new devices should use the bus ++ * interface (PCI) for low level management. ++ * ++ * int (*ndo_change_mtu)(struct net_device *dev, int new_mtu); ++ * Called when a user wants to change the Maximum Transfer Unit ++ * of a device. If not defined, any request to change MTU will ++ * will return an error. ++ * ++ * void (*ndo_tx_timeout)(struct net_device *dev); ++ * Callback uses when the transmitter has not made any progress ++ * for dev->watchdog ticks. ++ * ++ * struct net_device_stats* (*ndo_get_stats)(struct net_device *dev); ++ * Called when a user wants to get the network device usage ++ * statistics. If not defined, the counters in dev->stats will ++ * be used. ++ * ++ * void (*ndo_vlan_rx_register)(struct net_device *dev, struct vlan_group *grp); ++ * If device support VLAN receive accleration ++ * (ie. dev->features & NETIF_F_HW_VLAN_RX), then this function is called ++ * when vlan groups for the device changes. Note: grp is NULL ++ * if no vlan's groups are being used. ++ * ++ * void (*ndo_vlan_rx_add_vid)(struct net_device *dev, unsigned short vid); ++ * If device support VLAN filtering (dev->features & NETIF_F_HW_VLAN_FILTER) ++ * this function is called when a VLAN id is registered. ++ * ++ * void (*ndo_vlan_rx_kill_vid)(struct net_device *dev, unsigned short vid); ++ * If device support VLAN filtering (dev->features & NETIF_F_HW_VLAN_FILTER) ++ * this function is called when a VLAN id is unregistered. ++ * ++ * void (*ndo_poll_controller)(struct net_device *dev); ++ * ++ * SR-IOV management functions. ++ * int (*ndo_set_vf_mac)(struct net_device *dev, int vf, u8* mac); ++ * int (*ndo_set_vf_vlan)(struct net_device *dev, int vf, u16 vlan, u8 qos); ++ * int (*ndo_set_vf_tx_rate)(struct net_device *dev, int vf, int rate); ++ * int (*ndo_get_vf_config)(struct net_device *dev, ++ * int vf, struct ifla_vf_info *ivf); ++ */ ++#define HAVE_NET_DEVICE_OPS ++struct net_device_ops { ++ int (*ndo_init)(struct net_device *dev); ++ void (*ndo_uninit)(struct net_device *dev); ++ int (*ndo_open)(struct net_device *dev); ++ int (*ndo_stop)(struct net_device *dev); ++ netdev_tx_t (*ndo_start_xmit) (struct sk_buff *skb, ++ struct net_device *dev); ++ u16 (*ndo_select_queue)(struct net_device *dev, ++ struct sk_buff *skb); ++ void (*ndo_change_rx_flags)(struct net_device *dev, ++ int flags); ++ void (*ndo_set_rx_mode)(struct net_device *dev); ++ void (*ndo_set_multicast_list)(struct net_device *dev); ++ int (*ndo_set_mac_address)(struct net_device *dev, ++ void *addr); ++ int (*ndo_validate_addr)(struct net_device *dev); ++ int (*ndo_do_ioctl)(struct net_device *dev, ++ struct ifreq *ifr, int cmd); ++ int (*ndo_set_config)(struct net_device *dev, ++ struct ifmap *map); ++ int (*ndo_change_mtu)(struct net_device *dev, ++ int new_mtu); ++ int (*ndo_neigh_setup)(struct net_device *dev, ++ struct neigh_parms *); ++ void (*ndo_tx_timeout) (struct net_device *dev); ++ ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)) ++ struct rtnl_link_stats64* (*ndo_get_stats64)(struct net_device *dev, ++ struct rtnl_link_stats64 *storage); ++#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36)) */ ++ ++ struct net_device_stats* (*ndo_get_stats)(struct net_device *dev); ++ ++ void (*ndo_vlan_rx_register)(struct net_device *dev, ++ struct vlan_group *grp); ++ void (*ndo_vlan_rx_add_vid)(struct net_device *dev, ++ unsigned short vid); ++ void (*ndo_vlan_rx_kill_vid)(struct net_device *dev, ++ unsigned short vid); ++#ifdef CONFIG_NET_POLL_CONTROLLER ++ void (*ndo_poll_controller)(struct net_device *dev); ++#endif ++ int (*ndo_set_vf_mac)(struct net_device *dev, ++ int queue, u8 *mac); ++ int (*ndo_set_vf_vlan)(struct net_device *dev, ++ int queue, u16 vlan, u8 qos); ++ int (*ndo_set_vf_tx_rate)(struct net_device *dev, ++ int vf, int rate); ++/* ++ * The struct ifla_vf_info was added via b280da8d54b8d82b52f368a8703b7ada6c1744d5 ++ * on the v2.6.34-rc1~233^2~338 release ++ */ ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34)) ++ int (*ndo_get_vf_config)(struct net_device *dev, ++ int vf, ++ struct ifla_vf_info *ivf); ++#endif ++#if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE) ++ int (*ndo_fcoe_enable)(struct net_device *dev); ++ int (*ndo_fcoe_disable)(struct net_device *dev); ++ int (*ndo_fcoe_ddp_setup)(struct net_device *dev, ++ u16 xid, ++ struct scatterlist *sgl, ++ unsigned int sgc); ++ int (*ndo_fcoe_ddp_done)(struct net_device *dev, ++ u16 xid); ++#define NETDEV_FCOE_WWNN 0 ++#define NETDEV_FCOE_WWPN 1 ++ int (*ndo_fcoe_get_wwn)(struct net_device *dev, ++ u64 *wwn, int type); ++#endif ++}; ++ ++static inline int ndo_do_ioctl(struct net_device *dev, ++ struct ifreq *ifr, ++ int cmd) ++{ ++ if (dev->do_ioctl) ++ return dev->do_ioctl(dev, ifr, cmd); ++ return -EOPNOTSUPP; ++} ++ ++ ++#define netdev_attach_ops LINUX_BACKPORT(netdev_attach_ops) ++void netdev_attach_ops(struct net_device *dev, ++ const struct net_device_ops *ops); ++ ++/** ++ * skb_queue_is_first - check if skb is the first entry in the queue ++ * @list: queue head ++ * @skb: buffer ++ * ++ * Returns true if @skb is the first buffer on the list. ++ */ ++static inline bool skb_queue_is_first(const struct sk_buff_head *list, ++ const struct sk_buff *skb) ++{ ++ return (skb->prev == (struct sk_buff *) list); ++} ++ ++/** ++ * skb_queue_prev - return the prev packet in the queue ++ * @list: queue head ++ * @skb: current buffer ++ * ++ * Return the prev packet in @list before @skb. It is only valid to ++ * call this if skb_queue_is_first() evaluates to false. ++ */ ++static inline struct sk_buff *skb_queue_prev(const struct sk_buff_head *list, ++ const struct sk_buff *skb) ++{ ++ /* This BUG_ON may seem severe, but if we just return then we ++ * are going to dereference garbage. ++ */ ++ BUG_ON(skb_queue_is_first(list, skb)); ++ return skb->prev; ++} ++ ++ ++static inline struct net_device_stats *dev_get_stats(struct net_device *dev) ++{ ++ return dev->get_stats(dev); ++} ++ ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23)) ++#if defined(CONFIG_USB) || defined(CONFIG_USB_MODULE) ++#define usb_unpoison_anchored_urbs LINUX_BACKPORT(usb_unpoison_anchored_urbs) ++extern void usb_unpoison_anchored_urbs(struct usb_anchor *anchor); ++#endif /* CONFIG_USB */ ++#endif ++ ++#define DIV_ROUND_CLOSEST(x, divisor)( \ ++{ \ ++ typeof(divisor) __divisor = divisor; \ ++ (((x) + ((__divisor) / 2)) / (__divisor)); \ ++} \ ++) ++ ++#define eth_mac_addr LINUX_BACKPORT(eth_mac_addr) ++extern int eth_mac_addr(struct net_device *dev, void *p); ++#define eth_change_mtu LINUX_BACKPORT(eth_change_mtu) ++extern int eth_change_mtu(struct net_device *dev, int new_mtu); ++#define eth_validate_addr LINUX_BACKPORT(eth_validate_addr) ++extern int eth_validate_addr(struct net_device *dev); ++ ++#ifdef CONFIG_NET_NS ++ ++static inline void write_pnet(struct net **pnet, struct net *net) ++{ ++ *pnet = net; ++} ++ ++static inline struct net *read_pnet(struct net * const *pnet) ++{ ++ return *pnet; ++} ++ ++#else ++ ++#define write_pnet(pnet, net) do { (void)(net);} while (0) ++#define read_pnet(pnet) (&init_net) ++ ++/* ++ * swap - swap value of @a and @b ++ */ ++#define swap(a, b) \ ++ do { typeof(a) __tmp = (a); (a) = (b); (b) = __tmp; } while (0) ++ ++#endif ++ ++#define init_dummy_netdev LINUX_BACKPORT(init_dummy_netdev) ++extern int init_dummy_netdev(struct net_device *dev); ++ ++#else /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)) */ ++ ++/* Kernels >= 2.6.29 follows */ ++ ++/* XXX: this can probably just go upstream ! */ ++static inline void netdev_attach_ops(struct net_device *dev, ++ const struct net_device_ops *ops) ++{ ++ dev->netdev_ops = ops; ++} ++ ++/* XXX: this can probably just go upstream! */ ++static inline int ndo_do_ioctl(struct net_device *dev, ++ struct ifreq *ifr, ++ int cmd) ++{ ++ if (dev->netdev_ops && dev->netdev_ops->ndo_do_ioctl) ++ return dev->netdev_ops->ndo_do_ioctl(dev, ifr, cmd); ++ return -EOPNOTSUPP; ++} ++ ++#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)) */ ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29) ++#define compat_pci_suspend(fn) \ ++ int fn##_compat(struct pci_dev *pdev, pm_message_t state) \ ++ { \ ++ int r; \ ++ \ ++ r = fn(&pdev->dev); \ ++ if (r) \ ++ return r; \ ++ \ ++ pci_save_state(pdev); \ ++ pci_disable_device(pdev); \ ++ pci_set_power_state(pdev, PCI_D3hot); \ ++ \ ++ return 0; \ ++ } ++ ++#define compat_pci_resume(fn) \ ++ int fn##_compat(struct pci_dev *pdev) \ ++ { \ ++ int r; \ ++ \ ++ pci_set_power_state(pdev, PCI_D0); \ ++ r = pci_enable_device(pdev); \ ++ if (r) \ ++ return r; \ ++ pci_restore_state(pdev); \ ++ \ ++ return fn(&pdev->dev); \ ++ } ++#elif LINUX_VERSION_CODE == KERNEL_VERSION(2,6,29) ++#define compat_pci_suspend(fn) \ ++ int fn##_compat(struct device *dev) \ ++ { \ ++ struct pci_dev *pdev = to_pci_dev(dev); \ ++ int r; \ ++ \ ++ r = fn(&pdev->dev); \ ++ if (r) \ ++ return r; \ ++ \ ++ pci_save_state(pdev); \ ++ pci_disable_device(pdev); \ ++ pci_set_power_state(pdev, PCI_D3hot); \ ++ \ ++ return 0; \ ++ } ++ ++#define compat_pci_resume(fn) \ ++ int fn##_compat(struct device *dev) \ ++ { \ ++ struct pci_dev *pdev = to_pci_dev(dev); \ ++ int r; \ ++ \ ++ pci_set_power_state(pdev, PCI_D0); \ ++ r = pci_enable_device(pdev); \ ++ if (r) \ ++ return r; \ ++ pci_restore_state(pdev); \ ++ \ ++ return fn(&pdev->dev); \ ++ } ++#else ++#define compat_pci_suspend(fn) ++#define compat_pci_resume(fn) ++#endif ++ ++#define PCI_EXP_SLTSTA_PDS 0x0040 /* Presence Detect State */ ++ ++#endif /* LINUX_26_29_COMPAT_H */ diff --cc compat/include/linux/compat-2.6.30.h index 000000000000,000000000000..5841b6c8e348 new file mode 100644 --- /dev/null +++ b/compat/include/linux/compat-2.6.30.h @@@ -1,0 -1,0 +1,53 @@@ ++#ifndef LINUX_26_30_COMPAT_H ++#define LINUX_26_30_COMPAT_H ++ ++#include ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30)) ++ ++#include ++#include ++ ++#define HID_QUIRK_IGNORE 0x00000004 ++ ++#ifndef TP_PROTO ++#define TP_PROTO(args...) TPPROTO(args) ++#endif ++#ifndef TP_ARGS ++#define TP_ARGS(args...) TPARGS(args) ++#endif ++ ++#define IRQ_WAKE_THREAD (2) ++ ++/* From : include/linux/pm.h */ ++/* How to reorder dpm_list after device_move() */ ++enum dpm_order { ++ DPM_ORDER_NONE, ++ DPM_ORDER_DEV_AFTER_PARENT, ++ DPM_ORDER_PARENT_BEFORE_DEV, ++ DPM_ORDER_DEV_LAST, ++}; ++ ++static inline void dev_set_uevent_suppress(struct device *dev, int val) ++{ ++ dev->uevent_suppress = val; ++} ++ ++/* ++ * Print a one-time message (analogous to WARN_ONCE() et al): ++ */ ++#define printk_once(x...) ({ \ ++ static bool __print_once; \ ++ \ ++ if (!__print_once) { \ ++ __print_once = true; \ ++ printk(x); \ ++ } \ ++}) ++ ++#define PCI_EXP_LNKCTL2 48 /* Link Control 2 */ ++#define PCI_EXP_SLTCTL2 56 /* Slot Control 2 */ ++ ++#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30)) */ ++ ++#endif /* LINUX_26_30_COMPAT_H */ diff --cc compat/include/linux/compat-2.6.31.h index 000000000000,000000000000..096c13183470 new file mode 100644 --- /dev/null +++ b/compat/include/linux/compat-2.6.31.h @@@ -1,0 -1,0 +1,273 @@@ ++#ifndef LINUX_26_31_COMPAT_H ++#define LINUX_26_31_COMPAT_H ++ ++#include ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,31)) ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define SUPPORTED_Backplane (1 << 16) ++#define SUPPORTED_1000baseKX_Full (1 << 17) ++#define SUPPORTED_10000baseKX4_Full (1 << 18) ++#define SUPPORTED_10000baseKR_Full (1 << 19) ++#define SUPPORTED_10000baseR_FEC (1 << 20) ++ ++#define ADVERTISED_Backplane (1 << 16) ++#define ADVERTISED_1000baseKX_Full (1 << 17) ++#define ADVERTISED_10000baseKX4_Full (1 << 18) ++#define ADVERTISED_10000baseKR_Full (1 << 19) ++#define ADVERTISED_10000baseR_FEC (1 << 20) ++ ++#define rfkill_get_led_trigger_name LINUX_BACKPORT(rfkill_get_led_trigger_name) ++#define rfkill_set_led_trigger_name LINUX_BACKPORT(rfkill_set_led_trigger_name) ++#define rfkill_set_hw_state LINUX_BACKPORT(rfkill_set_hw_state) ++#define rfkill_set_sw_state LINUX_BACKPORT(rfkill_set_sw_state) ++#define rfkill_init_sw_state LINUX_BACKPORT(rfkill_init_sw_state) ++#define rfkill_set_states LINUX_BACKPORT(rfkill_set_states) ++#define rfkill_pause_polling LINUX_BACKPORT(rfkill_pause_polling) ++#define rfkill_resume_polling LINUX_BACKPORT(rfkill_resume_polling) ++#define rfkill_blocked LINUX_BACKPORT(rfkill_blocked) ++#define rfkill_alloc LINUX_BACKPORT(rfkill_alloc) ++#define rfkill_register LINUX_BACKPORT(rfkill_register) ++#define rfkill_unregister LINUX_BACKPORT(rfkill_unregister) ++#define rfkill_destroy LINUX_BACKPORT(rfkill_destroy) ++ ++#ifndef ERFKILL ++#if !defined(CONFIG_ALPHA) && !defined(CONFIG_MIPS) && !defined(CONFIG_PARISC) && !defined(CONFIG_SPARC) ++#define ERFKILL 132 /* Operation not possible due to RF-kill */ ++#endif ++#ifdef CONFIG_ALPHA ++#define ERFKILL 138 /* Operation not possible due to RF-kill */ ++#endif ++#ifdef CONFIG_MIPS ++#define ERFKILL 167 /* Operation not possible due to RF-kill */ ++#endif ++#ifdef CONFIG_PARISC ++#define ERFKILL 256 /* Operation not possible due to RF-kill */ ++#endif ++#ifdef CONFIG_SPARC ++#define ERFKILL 134 /* Operation not possible due to RF-kill */ ++#endif ++#endif ++ ++#define mdio45_probe LINUX_BACKPORT(mdio45_probe) ++#define mdio_set_flag LINUX_BACKPORT(mdio_set_flag) ++#define mdio45_links_ok LINUX_BACKPORT(mdio45_links_ok) ++#define mdio45_nway_restart LINUX_BACKPORT(mdio45_nway_restart) ++ ++#define mdio45_ethtool_gset_npage LINUX_BACKPORT(mdio45_ethtool_gset_npage) ++#define mdio45_ethtool_spauseparam_an LINUX_BACKPORT(mdio45_ethtool_spauseparam_an) ++#define mdio_mii_ioctl LINUX_BACKPORT(mdio_mii_ioctl) ++ ++#ifndef NETDEV_PRE_UP ++#define NETDEV_PRE_UP 0x000D ++#endif ++ ++#ifndef SDIO_DEVICE_ID_MARVELL_8688WLAN ++#define SDIO_DEVICE_ID_MARVELL_8688WLAN 0x9104 ++#endif ++ ++struct compat_threaded_irq { ++ unsigned int irq; ++ irq_handler_t handler; ++ irq_handler_t thread_fn; ++ void *dev_id; ++ char wq_name[64]; ++ struct workqueue_struct *wq; ++ struct work_struct work; ++}; ++ ++/* ++ * kmemleak was introduced on 2.6.31, since older kernels do not have ++ * we simply ignore its tuning. ++ */ ++static inline void kmemleak_ignore(const void *ptr) ++{ ++ return; ++} ++ ++static inline void kmemleak_not_leak(const void *ptr) ++{ ++ return; ++} ++ ++static inline void kmemleak_no_scan(const void *ptr) ++{ ++ return; ++} ++ ++/* ++ * Added via adf30907d63893e4208dfe3f5c88ae12bc2f25d5 ++ * ++ * There is no _sk_dst on older kernels, so just set the ++ * old dst to NULL and release it directly. ++ */ ++static inline void skb_dst_drop(struct sk_buff *skb) ++{ ++ dst_release(skb->dst); ++ skb->dst = NULL; ++} ++ ++static inline struct dst_entry *skb_dst(const struct sk_buff *skb) ++{ ++ return (struct dst_entry *)skb->dst; ++} ++ ++static inline void skb_dst_set(struct sk_buff *skb, struct dst_entry *dst) ++{ ++ skb->dst = dst; ++} ++ ++static inline struct rtable *skb_rtable(const struct sk_buff *skb) ++{ ++ return (struct rtable *)skb_dst(skb); ++} ++ ++/* Backport threaded IRQ support */ ++ ++static inline ++void compat_irq_work(struct work_struct *work) ++{ ++ struct compat_threaded_irq *comp = container_of(work, struct compat_threaded_irq, work); ++ comp->thread_fn(comp->irq, comp->dev_id); ++} ++ ++static inline ++irqreturn_t compat_irq_dispatcher(int irq, void *dev_id) ++{ ++ struct compat_threaded_irq *comp = dev_id; ++ irqreturn_t res; ++ ++ res = comp->handler(irq, comp->dev_id); ++ if (res == IRQ_WAKE_THREAD) { ++ queue_work(comp->wq, &comp->work); ++ res = IRQ_HANDLED; ++ } ++ ++ return res; ++} ++ ++static inline ++int compat_request_threaded_irq(struct compat_threaded_irq *comp, ++ unsigned int irq, ++ irq_handler_t handler, ++ irq_handler_t thread_fn, ++ unsigned long flags, ++ const char *name, ++ void *dev_id) ++{ ++ comp->irq = irq; ++ comp->handler = handler; ++ comp->thread_fn = thread_fn; ++ comp->dev_id = dev_id; ++ INIT_WORK(&comp->work, compat_irq_work); ++ ++ if (!comp->wq) { ++ snprintf(comp->wq_name, sizeof(comp->wq_name), ++ "compirq/%u-%s", irq, name); ++ comp->wq = create_singlethread_workqueue(comp->wq_name); ++ if (!comp->wq) { ++ printk(KERN_ERR "Failed to create compat-threaded-IRQ workqueue %s\n", ++ comp->wq_name); ++ return -ENOMEM; ++ } ++ } ++ return request_irq(irq, compat_irq_dispatcher, flags, name, comp); ++} ++ ++static inline ++void compat_free_threaded_irq(struct compat_threaded_irq *comp) ++{ ++ free_irq(comp->irq, comp); ++} ++ ++static inline ++void compat_destroy_threaded_irq(struct compat_threaded_irq *comp) ++{ ++ if (comp->wq) ++ destroy_workqueue(comp->wq); ++ comp->wq = NULL; ++} ++ ++static inline ++void compat_synchronize_threaded_irq(struct compat_threaded_irq *comp) ++{ ++ synchronize_irq(comp->irq); ++ cancel_work_sync(&comp->work); ++} ++ ++/** ++ * list_entry_rcu - get the struct for this entry ++ * @ptr: the &struct list_head pointer. ++ * @type: the type of the struct this is embedded in. ++ * @member: the name of the list_struct within the struct. ++ * ++ * This primitive may safely run concurrently with the _rcu list-mutation ++ * primitives such as list_add_rcu() as long as it's guarded by rcu_read_lock(). ++ */ ++#define list_entry_rcu(ptr, type, member) \ ++ container_of(rcu_dereference(ptr), type, member) ++ ++#define skb_walk_frags(skb, iter) \ ++ for (iter = skb_shinfo(skb)->frag_list; iter; iter = iter->next) ++ ++#ifndef CONFIG_64BIT ++ ++typedef struct { ++ long long counter; ++} atomic64_t; ++ ++#define atomic64_read LINUX_BACKPORT(atomic64_read) ++extern long long atomic64_read(const atomic64_t *v); ++#define atomic64_add_return LINUX_BACKPORT(atomic64_add_return) ++extern long long atomic64_add_return(long long a, atomic64_t *v); ++ ++#define atomic64_inc_return(v) atomic64_add_return(1LL, (v)) ++ ++#endif ++ ++/** ++ * sk_rmem_alloc_get - returns read allocations ++ * @sk: socket ++ * ++ * Returns sk_rmem_alloc ++ */ ++static inline int sk_rmem_alloc_get(const struct sock *sk) ++{ ++ return atomic_read(&sk->sk_rmem_alloc); ++} ++ ++/** ++ * sk_wmem_alloc_get - returns write allocations ++ * @sk: socket ++ * ++ * Returns sk_wmem_alloc minus initial offset of one ++ */ ++static inline int sk_wmem_alloc_get(const struct sock *sk) ++{ ++ return atomic_read(&sk->sk_wmem_alloc) - 1; ++} ++ ++/** ++ * sk_has_allocations - check if allocations are outstanding ++ * @sk: socket ++ * ++ * Returns true if socket has write or read allocations ++ */ ++static inline bool sk_has_allocations(const struct sock *sk) ++{ ++ return sk_wmem_alloc_get(sk) || sk_rmem_alloc_get(sk); ++} ++ ++#define USB_SUBCLASS_VENDOR_SPEC 0xff ++ ++#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,31)) */ ++ ++#endif /* LINUX_26_31_COMPAT_H */ diff --cc compat/include/linux/compat-2.6.32.h index 000000000000,000000000000..d5b5df87a17b new file mode 100644 --- /dev/null +++ b/compat/include/linux/compat-2.6.32.h @@@ -1,0 -1,0 +1,198 @@@ ++#ifndef LINUX_26_32_COMPAT_H ++#define LINUX_26_32_COMPAT_H ++ ++#include ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32)) ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define TCQ_F_CAN_BYPASS 4 ++ ++static inline int qdisc_qlen(const struct Qdisc *q) ++{ ++ return q->q.qlen; ++} ++ ++#define SDIO_VENDOR_ID_INTEL 0x0089 ++#define SDIO_DEVICE_ID_INTEL_IWMC3200WIMAX 0x1402 ++#define SDIO_DEVICE_ID_INTEL_IWMC3200WIFI 0x1403 ++#define SDIO_DEVICE_ID_INTEL_IWMC3200TOP 0x1404 ++#define SDIO_DEVICE_ID_INTEL_IWMC3200GPS 0x1405 ++#define SDIO_DEVICE_ID_INTEL_IWMC3200BT 0x1406 ++ ++/* ++ * Backports 5e928f77a09a07f9dd595bb8a489965d69a83458 ++ * run-time power management cannot really be backported ++ * given that the implementation added bus specific ++ * callbacks that we won't have on older kernels. If ++ * you really want run-time power management or good ++ * power management upgrade your kernel. We'll just ++ * compile this out as if run-time power management was ++ * disabled just as the kernel disables run-time power management ++ * when CONFIG_PM_RUNTIME is disabled. ++ */ ++static inline void pm_runtime_init(struct device *dev) {} ++static inline void pm_runtime_remove(struct device *dev) {} ++static inline int pm_runtime_get(struct device *dev) ++{ ++ return 0; ++} ++ ++static inline int pm_runtime_get_sync(struct device *dev) ++{ ++ return 0; ++} ++ ++static inline int pm_runtime_put(struct device *dev) ++{ ++ return 0; ++} ++ ++static inline int pm_runtime_put_sync(struct device *dev) ++{ ++ return 0; ++} ++ ++static inline int pm_runtime_set_active(struct device *dev) ++{ ++ return 0; ++} ++ ++static inline void pm_runtime_set_suspended(struct device *dev) ++{ ++} ++ ++static inline void pm_runtime_disable(struct device *dev) ++{ ++} ++ ++static inline void pm_runtime_put_noidle(struct device *dev) {} ++static inline void pm_runtime_get_noresume(struct device *dev) {} ++ ++static inline void flush_delayed_work(struct delayed_work *dwork) ++{ ++ if (del_timer_sync(&dwork->timer)) { ++ /* ++ * This is what would happen on 2.6.32 but since we don't have ++ * access to the singlethread_cpu we can't really backport this, ++ * so avoid really *flush*ing the work... Oh well. Any better ideas? ++ ++ struct cpu_workqueue_struct *cwq; ++ cwq = wq_per_cpu(keventd_wq, get_cpu()); ++ __queue_work(cwq, &dwork->work); ++ put_cpu(); ++ ++ */ ++ } ++ flush_work(&dwork->work); ++} ++ ++/* ++ * struct genl_multicast_group was made netns aware through ++ * patch "genetlink: make netns aware" by johannes, we just ++ * force this to always use the default init_net ++ */ ++#define genl_info_net(x) &init_net ++/* Just use init_net for older kernels */ ++#define get_net_ns_by_pid(x) &init_net ++ ++/* net namespace is lost */ ++#define genlmsg_multicast_netns(a, b, c, d, e) genlmsg_multicast(b, c, d, e) ++#define genlmsg_multicast_allns(a, b, c, d) genlmsg_multicast(a, b, c, d) ++#define genlmsg_unicast(net, skb, pid) genlmsg_unicast(skb, pid) ++ ++#define dev_change_net_namespace(a, b, c) (-EOPNOTSUPP) ++ ++#define SET_NETDEV_DEVTYPE(netdev, type) ++ ++#ifdef __KERNEL__ ++/* Driver transmit return codes */ ++enum netdev_tx { ++ BACKPORT_NETDEV_TX_OK = NETDEV_TX_OK, /* driver took care of packet */ ++ BACKPORT_NETDEV_TX_BUSY = NETDEV_TX_BUSY, /* driver tx path was busy*/ ++ BACKPORT_NETDEV_TX_LOCKED = NETDEV_TX_LOCKED, /* driver tx lock was already taken */ ++}; ++typedef enum netdev_tx netdev_tx_t; ++#endif /* __KERNEL__ */ ++ ++/* ++ * dev_pm_ops is only available on kernels >= 2.6.29, for ++ * older kernels we rely on reverting the work to old ++ * power management style stuff. On 2.6.29 the pci calls ++ * weren't included yet though, so include them here. ++ */ ++#if (LINUX_VERSION_CODE == KERNEL_VERSION(2,6,29)) ++#define SIMPLE_DEV_PM_OPS(name, suspend_fn, resume_fn) \ ++struct dev_pm_ops name = { \ ++ .suspend = suspend_fn ## _compat, \ ++ .resume = resume_fn ## _compat, \ ++ .freeze = suspend_fn ## _compat, \ ++ .thaw = resume_fn ## _compat, \ ++ .poweroff = suspend_fn ## _compat, \ ++ .restore = resume_fn ## _compat, \ ++} ++#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,30)) ++/* ++ * Use this if you want to use the same suspend and resume callbacks for suspend ++ * to RAM and hibernation. ++ */ ++#define SIMPLE_DEV_PM_OPS(name, suspend_fn, resume_fn) \ ++struct dev_pm_ops name = { \ ++ .suspend = suspend_fn, \ ++ .resume = resume_fn, \ ++ .freeze = suspend_fn, \ ++ .thaw = resume_fn, \ ++ .poweroff = suspend_fn, \ ++ .restore = resume_fn, \ ++} ++#else ++#define SIMPLE_DEV_PM_OPS(name, suspend_fn, resume_fn) ++#endif /* >= 2.6.29 */ ++ ++#define wireless_send_event(a, b, c, d) wireless_send_event(a, b, c, (char * ) d) ++ ++/* The export symbol in changed in compat/patches/15-symbol-export-conflicts.patch */ ++#define ieee80211_rx(hw, skb) mac80211_ieee80211_rx(hw, skb) ++ ++#define dev_to_sdio_func(d) container_of(d, struct sdio_func, dev) ++ ++#define lockdep_assert_held(l) do { } while (0) ++ ++/* ++ * Similar to the struct tm in userspace , but it needs to be here so ++ * that the kernel source is self contained. ++ */ ++struct tm { ++ /* ++ * the number of seconds after the minute, normally in the range ++ * 0 to 59, but can be up to 60 to allow for leap seconds ++ */ ++ int tm_sec; ++ /* the number of minutes after the hour, in the range 0 to 59*/ ++ int tm_min; ++ /* the number of hours past midnight, in the range 0 to 23 */ ++ int tm_hour; ++ /* the day of the month, in the range 1 to 31 */ ++ int tm_mday; ++ /* the number of months since January, in the range 0 to 11 */ ++ int tm_mon; ++ /* the number of years since 1900 */ ++ long tm_year; ++ /* the number of days since Sunday, in the range 0 to 6 */ ++ int tm_wday; ++ /* the number of days since January 1, in the range 0 to 365 */ ++ int tm_yday; ++}; ++ ++#define time_to_tm LINUX_BACKPORT(time_to_tm) ++void time_to_tm(time_t totalsecs, int offset, struct tm *result); ++ ++#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32)) */ ++ ++#endif /* LINUX_26_32_COMPAT_H */ diff --cc compat/include/linux/compat-2.6.33.h index 000000000000,000000000000..c0be190e02ba new file mode 100644 --- /dev/null +++ b/compat/include/linux/compat-2.6.33.h @@@ -1,0 -1,0 +1,210 @@@ ++#ifndef LINUX_26_33_COMPAT_H ++#define LINUX_26_33_COMPAT_H ++ ++#include ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33)) ++ ++#include ++#include ++#include ++#if defined(CONFIG_PCCARD) || defined(CONFIG_PCCARD_MODULE) ++#include ++#include ++#include ++#endif ++#include ++#include ++ ++#define usb_autopm_get_interface_no_resume LINUX_BACKPORT(usb_autopm_get_interface_no_resume) ++#define usb_autopm_put_interface_no_suspend LINUX_BACKPORT(usb_autopm_put_interface_no_suspend) ++#ifdef CONFIG_USB_SUSPEND ++extern void usb_autopm_get_interface_no_resume(struct usb_interface *intf); ++extern void usb_autopm_put_interface_no_suspend(struct usb_interface *intf); ++#else ++static inline void usb_autopm_get_interface_no_resume(struct usb_interface *intf) ++{ ++ atomic_inc(&intf->pm_usage_cnt); ++} ++static inline void usb_autopm_put_interface_no_suspend(struct usb_interface *intf) ++{ ++ atomic_dec(&intf->pm_usage_cnt); ++} ++#endif /* CONFIG_USB_SUSPEND */ ++ ++#if defined(CONFIG_COMPAT_FIRMWARE_CLASS) ++#define request_firmware_nowait LINUX_BACKPORT(request_firmware_nowait) ++#define request_firmware LINUX_BACKPORT(request_firmware) ++#define release_firmware LINUX_BACKPORT(release_firmware) ++ ++#if defined(CONFIG_FW_LOADER) || defined(CONFIG_FW_LOADER_MODULE) ++int request_firmware(const struct firmware **fw, const char *name, ++ struct device *device); ++int request_firmware_nowait( ++ struct module *module, int uevent, ++ const char *name, struct device *device, gfp_t gfp, void *context, ++ void (*cont)(const struct firmware *fw, void *context)); ++ ++void release_firmware(const struct firmware *fw); ++#else ++static inline int request_firmware(const struct firmware **fw, ++ const char *name, ++ struct device *device) ++{ ++ return -EINVAL; ++} ++static inline int request_firmware_nowait( ++ struct module *module, int uevent, ++ const char *name, struct device *device, gfp_t gfp, void *context, ++ void (*cont)(const struct firmware *fw, void *context)) ++{ ++ return -EINVAL; ++} ++ ++static inline void release_firmware(const struct firmware *fw) ++{ ++} ++#endif ++#endif ++ ++/* mask KEY_RFKILL as RHEL6 backports this */ ++#if !defined(KEY_RFKILL) ++#define KEY_RFKILL 247 /* Key that controls all radios */ ++#endif ++ ++/* mask IFF_DONT_BRIDGE as RHEL6 backports this */ ++#if !defined(IFF_DONT_BRIDGE) ++#define IFF_DONT_BRIDGE 0x800 /* disallow bridging this ether dev */ ++/* source: include/linux/if.h */ ++#endif ++ ++/* mask NETDEV_POST_INIT as RHEL6 backports this */ ++/* this will never happen on older kernels */ ++#if !defined(NETDEV_POST_INIT) ++#define NETDEV_POST_INIT 0xffff ++#endif ++ ++/* mask netdev_alloc_skb_ip_align as debian squeeze also backports this */ ++#define netdev_alloc_skb_ip_align(a, b) compat_netdev_alloc_skb_ip_align(a, b) ++ ++static inline struct sk_buff *netdev_alloc_skb_ip_align(struct net_device *dev, ++ unsigned int length) ++{ ++ struct sk_buff *skb = netdev_alloc_skb(dev, length + NET_IP_ALIGN); ++ ++ if (NET_IP_ALIGN && skb) ++ skb_reserve(skb, NET_IP_ALIGN); ++ return skb; ++} ++ ++#if defined(CONFIG_PCCARD) || defined(CONFIG_PCCARD_MODULE) ++ ++#if defined(CONFIG_PCMCIA) || defined(CONFIG_PCMCIA_MODULE) ++ ++#define pcmcia_request_window(a, b, c) pcmcia_request_window(&a, b, c) ++ ++#define pcmcia_map_mem_page(a, b, c) pcmcia_map_mem_page(b, c) ++ ++/* loop over CIS entries */ ++#define pcmcia_loop_tuple LINUX_BACKPORT(pcmcia_loop_tuple) ++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); ++ ++#endif /* CONFIG_PCMCIA */ ++ ++/* loop over CIS entries */ ++#define pccard_loop_tuple LINUX_BACKPORT(pccard_loop_tuple) ++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)); ++ ++#endif /* CONFIG_PCCARD */ ++ ++/** ++ * list_for_each_entry_continue_rcu - continue iteration over list of given type ++ * @pos: the type * to use as a loop cursor. ++ * @head: the head for your list. ++ * @member: the name of the list_struct within the struct. ++ * ++ * Continue to iterate over list of given type, continuing after ++ * the current position. ++ */ ++#define list_for_each_entry_continue_rcu(pos, head, member) \ ++ for (pos = list_entry_rcu(pos->member.next, typeof(*pos), member); \ ++ prefetch(pos->member.next), &pos->member != (head); \ ++ pos = list_entry_rcu(pos->member.next, typeof(*pos), member)) ++ ++#define sock_recv_ts_and_drops(msg, sk, skb) sock_recv_timestamp(msg, sk, skb) ++ ++/* mask pci_pcie_cap as debian squeeze also backports this */ ++#define pci_pcie_cap(a) compat_pci_pcie_cap(a) ++ ++/** ++ * pci_pcie_cap - get the saved PCIe capability offset ++ * @dev: PCI device ++ * ++ * PCIe capability offset is calculated at PCI device initialization ++ * time and saved in the data structure. This function returns saved ++ * PCIe capability offset. Using this instead of pci_find_capability() ++ * reduces unnecessary search in the PCI configuration space. If you ++ * need to calculate PCIe capability offset from raw device for some ++ * reasons, please use pci_find_capability() instead. ++ */ ++static inline int pci_pcie_cap(struct pci_dev *dev) ++{ ++ return pci_find_capability(dev, PCI_CAP_ID_EXP); ++} ++ ++/* mask pci_is_pcie as RHEL6 backports this */ ++#define pci_is_pcie(a) compat_pci_is_pcie(a) ++ ++/** ++ * pci_is_pcie - check if the PCI device is PCI Express capable ++ * @dev: PCI device ++ * ++ * Retrun true if the PCI device is PCI Express capable, false otherwise. ++ */ ++static inline bool pci_is_pcie(struct pci_dev *dev) ++{ ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)) ++ return dev->is_pcie; ++#else ++ return !!pci_pcie_cap(dev); ++#endif ++} ++ ++#ifdef __GNUC__ ++#define __always_unused __attribute__((unused)) ++#else ++#define __always_unused /* unimplemented */ ++#endif ++ ++/* mask IS_ERR_OR_NULL as debian squeeze also backports this */ ++#define IS_ERR_OR_NULL(a) compat_IS_ERR_OR_NULL(a) ++ ++static inline long __must_check IS_ERR_OR_NULL(const void *ptr) ++{ ++ return !ptr || IS_ERR_VALUE((unsigned long)ptr); ++} ++ ++#if (LINUX_VERSION_CODE == KERNEL_VERSION(2,6,32)) ++#undef SIMPLE_DEV_PM_OPS ++#define SIMPLE_DEV_PM_OPS(name, suspend_fn, resume_fn) \ ++const struct dev_pm_ops name = { \ ++ .suspend = suspend_fn, \ ++ .resume = resume_fn, \ ++ .freeze = suspend_fn, \ ++ .thaw = resume_fn, \ ++ .poweroff = suspend_fn, \ ++ .restore = resume_fn, \ ++} ++#endif /* (LINUX_VERSION_CODE == KERNEL_VERSION(2,6,32)) */ ++ ++#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33)) */ ++ ++#endif /* LINUX_26_33_COMPAT_H */ diff --cc compat/include/linux/compat-2.6.34.h index 000000000000,000000000000..09d592290965 new file mode 100644 --- /dev/null +++ b/compat/include/linux/compat-2.6.34.h @@@ -1,0 -1,0 +1,345 @@@ ++#ifndef LINUX_26_34_COMPAT_H ++#define LINUX_26_34_COMPAT_H ++ ++#include ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,34)) ++ ++#include ++#include ++#include ++#include ++ ++/* ++ * Backports da68c4eb25 ++ * sdio: introduce API for special power management features ++ * ++ * We wimply carry around the data structures and flags, and ++ * make the host return no flags set by the driver. ++ */ ++typedef unsigned int mmc_pm_flag_t; ++ ++#define MMC_PM_KEEP_POWER (1 << 0) /* preserve card power during suspend */ ++#define MMC_PM_WAKE_SDIO_IRQ (1 << 1) /* wake up host system on SDIO IRQ assertion */ ++ ++extern mmc_pm_flag_t sdio_get_host_pm_caps(struct sdio_func *func); ++extern int sdio_set_host_pm_flags(struct sdio_func *func, mmc_pm_flag_t flags); ++ ++#define netdev_mc_count(dev) ((dev)->mc_count) ++#define netdev_mc_empty(dev) (netdev_mc_count(dev) == 0) ++ ++/* mask netdev_for_each_mc_addr as RHEL6 backports this */ ++#if !defined(netdev_for_each_mc_addr) ++#define netdev_for_each_mc_addr(mclist, dev) \ ++ for (mclist = dev->mc_list; mclist; mclist = mclist->next) ++#endif ++/* source: include/linux/netdevice.h */ ++ ++ ++/* Logging, debugging and troubleshooting/diagnostic helpers. */ ++ ++/* netdev_printk helpers, similar to dev_printk */ ++ ++#ifndef netdev_name ++#define netdev_name(__dev) \ ++ ((__dev->reg_state != NETREG_REGISTERED) ? \ ++ "(unregistered net_device)" : __dev->name) ++#endif ++ ++#define netdev_printk(level, netdev, format, args...) \ ++ dev_printk(level, (netdev)->dev.parent, \ ++ "%s: " format, \ ++ netdev_name(netdev), ##args) ++ ++#define netdev_emerg(dev, format, args...) \ ++ netdev_printk(KERN_EMERG, dev, format, ##args) ++#define netdev_alert(dev, format, args...) \ ++ netdev_printk(KERN_ALERT, dev, format, ##args) ++#define netdev_crit(dev, format, args...) \ ++ netdev_printk(KERN_CRIT, dev, format, ##args) ++#define netdev_err(dev, format, args...) \ ++ netdev_printk(KERN_ERR, dev, format, ##args) ++#define netdev_warn(dev, format, args...) \ ++ netdev_printk(KERN_WARNING, dev, format, ##args) ++#define netdev_notice(dev, format, args...) \ ++ netdev_printk(KERN_NOTICE, dev, format, ##args) ++#define netdev_info(dev, format, args...) \ ++ netdev_printk(KERN_INFO, dev, format, ##args) ++ ++/* mask netdev_dbg as RHEL6 backports this */ ++#if !defined(netdev_dbg) ++ ++#if defined(DEBUG) ++#define netdev_dbg(__dev, format, args...) \ ++ netdev_printk(KERN_DEBUG, __dev, format, ##args) ++#elif defined(CONFIG_DYNAMIC_DEBUG) ++#define netdev_dbg(__dev, format, args...) \ ++do { \ ++ dynamic_dev_dbg((__dev)->dev.parent, "%s: " format, \ ++ netdev_name(__dev), ##args); \ ++} while (0) ++#else ++#define netdev_dbg(__dev, format, args...) \ ++({ \ ++ if (0) \ ++ netdev_printk(KERN_DEBUG, __dev, format, ##args); \ ++ 0; \ ++}) ++#endif ++ ++#endif ++ ++/* mask netdev_vdbg as RHEL6 backports this */ ++#if !defined(netdev_dbg) ++ ++#if defined(VERBOSE_DEBUG) ++#define netdev_vdbg netdev_dbg ++#else ++ ++#define netdev_vdbg(dev, format, args...) \ ++({ \ ++ if (0) \ ++ netdev_printk(KERN_DEBUG, dev, format, ##args); \ ++ 0; \ ++}) ++#endif ++ ++#endif ++ ++/* ++ * netdev_WARN() acts like dev_printk(), but with the key difference ++ * of using a WARN/WARN_ON to get the message out, including the ++ * file/line information and a backtrace. ++ */ ++#define netdev_WARN(dev, format, args...) \ ++ WARN(1, "netdevice: %s\n" format, netdev_name(dev), ##args); ++ ++/* netif printk helpers, similar to netdev_printk */ ++ ++#define netif_printk(priv, type, level, dev, fmt, args...) \ ++do { \ ++ if (netif_msg_##type(priv)) \ ++ netdev_printk(level, (dev), fmt, ##args); \ ++} while (0) ++ ++#define netif_emerg(priv, type, dev, fmt, args...) \ ++ netif_printk(priv, type, KERN_EMERG, dev, fmt, ##args) ++#define netif_alert(priv, type, dev, fmt, args...) \ ++ netif_printk(priv, type, KERN_ALERT, dev, fmt, ##args) ++#define netif_crit(priv, type, dev, fmt, args...) \ ++ netif_printk(priv, type, KERN_CRIT, dev, fmt, ##args) ++#define netif_err(priv, type, dev, fmt, args...) \ ++ netif_printk(priv, type, KERN_ERR, dev, fmt, ##args) ++#define netif_warn(priv, type, dev, fmt, args...) \ ++ netif_printk(priv, type, KERN_WARNING, dev, fmt, ##args) ++#define netif_notice(priv, type, dev, fmt, args...) \ ++ netif_printk(priv, type, KERN_NOTICE, dev, fmt, ##args) ++#define netif_info(priv, type, dev, fmt, args...) \ ++ netif_printk(priv, type, KERN_INFO, (dev), fmt, ##args) ++ ++/* mask netif_dbg as RHEL6 backports this */ ++#if !defined(netif_dbg) ++ ++#if defined(DEBUG) ++#define netif_dbg(priv, type, dev, format, args...) \ ++ netif_printk(priv, type, KERN_DEBUG, dev, format, ##args) ++#elif defined(CONFIG_DYNAMIC_DEBUG) ++#define netif_dbg(priv, type, netdev, format, args...) \ ++do { \ ++ if (netif_msg_##type(priv)) \ ++ dynamic_dev_dbg((netdev)->dev.parent, \ ++ "%s: " format, \ ++ netdev_name(netdev), ##args); \ ++} while (0) ++#else ++#define netif_dbg(priv, type, dev, format, args...) \ ++({ \ ++ if (0) \ ++ netif_printk(priv, type, KERN_DEBUG, dev, format, ##args); \ ++ 0; \ ++}) ++#endif ++ ++#endif ++ ++/* mask netif_vdbg as RHEL6 backports this */ ++#if !defined(netif_vdbg) ++ ++#if defined(VERBOSE_DEBUG) ++#define netif_vdbg netdev_dbg ++#else ++#define netif_vdbg(priv, type, dev, format, args...) \ ++({ \ ++ if (0) \ ++ netif_printk(KERN_DEBUG, dev, format, ##args); \ ++ 0; \ ++}) ++#endif ++#endif ++/* source: include/linux/netdevice.h */ ++ ++ ++static inline void device_lock(struct device *dev) ++{ ++#if defined(CONFIG_PREEMPT_RT) || defined(CONFIG_PREEMPT_DESKTOP) ++ mutex_lock(&dev->mutex); ++#else ++ down(&dev->sem); ++#endif ++} ++ ++static inline int device_trylock(struct device *dev) ++{ ++#if defined(CONFIG_PREEMPT_RT) || defined(CONFIG_PREEMPT_DESKTOP) ++ return mutex_trylock(&dev->mutex); ++#else ++ return down_trylock(&dev->sem); ++#endif ++} ++ ++static inline void device_unlock(struct device *dev) ++{ ++#if defined(CONFIG_PREEMPT_RT) || defined(CONFIG_PREEMPT_DESKTOP) ++ mutex_unlock(&dev->mutex); ++#else ++ up(&dev->sem); ++#endif ++} ++ ++#if defined(CONFIG_PCMCIA) || defined(CONFIG_PCMCIA_MODULE) ++#define PCMCIA_DEVICE_PROD_ID3(v3, vh3) { \ ++ .match_flags = PCMCIA_DEV_ID_MATCH_PROD_ID3, \ ++ .prod_id = { NULL, NULL, (v3), NULL }, \ ++ .prod_id_hash = { 0, 0, (vh3), 0 }, } ++#endif ++ ++#define rcu_dereference_check(p, c) rcu_dereference(p) ++ ++/** ++ * sysfs_attr_init - initialize a dynamically allocated sysfs attribute ++ * @attr: struct attribute to initialize ++ * ++ * Initialize a dynamically allocated struct attribute so we can ++ * make lockdep happy. This is a new requirement for attributes ++ * and initially this is only needed when lockdep is enabled. ++ * Lockdep gives a nice error when your attribute is added to ++ * sysfs if you don't have this. ++ */ ++#ifdef CONFIG_DEBUG_LOCK_ALLOC ++#define sysfs_attr_init(attr) \ ++do { \ ++ static struct lock_class_key __key; \ ++ \ ++ (attr)->key = &__key; \ ++} while(0) ++#else ++#define sysfs_attr_init(attr) do {} while(0) ++#endif ++ ++/* mask sysfs_bin_attr_init as RHEL6 backports this */ ++#if !defined(sysfs_bin_attr_init) ++/** ++ * sysfs_bin_attr_init - initialize a dynamically allocated bin_attribute ++ * @attr: struct bin_attribute to initialize ++ * ++ * Initialize a dynamically allocated struct bin_attribute so we ++ * can make lockdep happy. This is a new requirement for ++ * attributes and initially this is only needed when lockdep is ++ * enabled. Lockdep gives a nice error when your attribute is ++ * added to sysfs if you don't have this. ++ */ ++#define sysfs_bin_attr_init(bin_attr) sysfs_attr_init(&(bin_attr)->attr) ++#endif ++ ++#define usb_alloc_coherent(dev, size, mem_flags, dma) usb_buffer_alloc(dev, size, mem_flags, dma) ++#define usb_free_coherent(dev, size, addr, dma) usb_buffer_free(dev, size, addr, dma) ++ ++/* only include this if DEFINE_DMA_UNMAP_ADDR is not set as debian squeeze also backports this */ ++#ifndef DEFINE_DMA_UNMAP_ADDR ++#ifdef CONFIG_NEED_DMA_MAP_STATE ++#define DEFINE_DMA_UNMAP_ADDR(ADDR_NAME) dma_addr_t ADDR_NAME ++#define DEFINE_DMA_UNMAP_LEN(LEN_NAME) __u32 LEN_NAME ++#define dma_unmap_addr(PTR, ADDR_NAME) ((PTR)->ADDR_NAME) ++#define dma_unmap_addr_set(PTR, ADDR_NAME, VAL) (((PTR)->ADDR_NAME) = (VAL)) ++#define dma_unmap_len(PTR, LEN_NAME) ((PTR)->LEN_NAME) ++#define dma_unmap_len_set(PTR, LEN_NAME, VAL) (((PTR)->LEN_NAME) = (VAL)) ++#else ++#define DEFINE_DMA_UNMAP_ADDR(ADDR_NAME) ++#define DEFINE_DMA_UNMAP_LEN(LEN_NAME) ++#define dma_unmap_addr(PTR, ADDR_NAME) (0) ++#define dma_unmap_addr_set(PTR, ADDR_NAME, VAL) do { } while (0) ++#define dma_unmap_len(PTR, LEN_NAME) (0) ++#define dma_unmap_len_set(PTR, LEN_NAME, VAL) do { } while (0) ++#endif ++#endif ++ ++/* mask dma_set_coherent_mask as debian squeeze also backports this */ ++#define dma_set_coherent_mask(a, b) compat_dma_set_coherent_mask(a, b) ++ ++static inline int dma_set_coherent_mask(struct device *dev, u64 mask) ++{ ++ if (!dma_supported(dev, mask)) ++ return -EIO; ++ dev->coherent_dma_mask = mask; ++ return 0; ++} ++ ++/* USB autosuspend and autoresume */ ++static inline int usb_enable_autosuspend(struct usb_device *udev) ++{ return 0; } ++static inline int usb_disable_autosuspend(struct usb_device *udev) ++{ return 0; } ++ ++#define rcu_dereference_protected(p, c) (p) ++#define rcu_access_pointer(p) ACCESS_ONCE(p) ++ ++#define rcu_dereference_raw(p) rcu_dereference(p) ++ ++#define KEY_WPS_BUTTON 0x211 /* WiFi Protected Setup key */ ++ ++/* ++ * This looks more complex than it should be. But we need to ++ * get the type for the ~ right in round_down (it needs to be ++ * as wide as the result!), and we want to evaluate the macro ++ * arguments just once each. ++ */ ++#define __round_mask(x, y) ((__typeof__(x))((y)-1)) ++#define round_up(x, y) ((((x)-1) | __round_mask(x, y))+1) ++#define round_down(x, y) ((x) & ~__round_mask(x, y)) ++ ++static inline int rcu_read_lock_held(void) ++{ ++ return 1; ++} ++ ++#ifdef CONFIG_PROVE_LOCKING ++/* ++ * Obviously, this is wrong. But the base kernel will have rtnl_mutex ++ * declared static, with no way to access it. I think this is the best ++ * we can do... ++ */ ++static inline int lockdep_rtnl_is_held(void) ++{ ++ return 1; ++} ++#endif /* #ifdef CONFIG_PROVE_LOCKING */ ++ ++#define seq_hlist_start_head LINUX_BACKPORT(seq_hlist_start_head) ++extern struct hlist_node *seq_hlist_start_head(struct hlist_head *head, ++ loff_t pos); ++ ++#define seq_hlist_next LINUX_BACKPORT(seq_hlist_next) ++extern struct hlist_node *seq_hlist_next(void *v, struct hlist_head *head, ++ loff_t *ppos); ++ ++static inline struct sock *sk_entry(const struct hlist_node *node) ++{ ++ return hlist_entry(node, struct sock, sk_node); ++} ++ ++#else /* Kernels >= 2.6.34 */ ++ ++#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,34)) */ ++ ++ ++#endif /* LINUX_26_34_COMPAT_H */ diff --cc compat/include/linux/compat-2.6.35.h index 000000000000,000000000000..99968bf2218e new file mode 100644 --- /dev/null +++ b/compat/include/linux/compat-2.6.35.h @@@ -1,0 -1,0 +1,97 @@@ ++#ifndef LINUX_26_35_COMPAT_H ++#define LINUX_26_35_COMPAT_H ++ ++#include ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35)) ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define HID_QUIRK_NO_IGNORE 0x40000000 ++#define HID_QUIRK_HIDDEV_FORCE 0x00000010 ++ ++/* added on linux/kernel.h */ ++#define USHRT_MAX ((u16)(~0U)) ++#define SHRT_MAX ((s16)(USHRT_MAX>>1)) ++#define SHRT_MIN ((s16)(-SHRT_MAX - 1)) ++ ++#define SDIO_BUS_ECSI 0x20 /* Enable continuous SPI interrupt */ ++#define SDIO_BUS_SCSI 0x40 /* Support continuous SPI interrupt */ ++ ++#define netdev_hw_addr dev_mc_list ++ ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)) ++/* Reset all TX qdiscs greater then index of a device. */ ++static inline void qdisc_reset_all_tx_gt(struct net_device *dev, unsigned int i) ++{ ++ struct Qdisc *qdisc; ++ ++ for (; i < dev->num_tx_queues; i++) { ++ qdisc = netdev_get_tx_queue(dev, i)->qdisc; ++ if (qdisc) { ++ spin_lock_bh(qdisc_lock(qdisc)); ++ qdisc_reset(qdisc); ++ spin_unlock_bh(qdisc_lock(qdisc)); ++ } ++ } ++} ++#else ++static inline void qdisc_reset_all_tx_gt(struct net_device *dev, unsigned int i) ++{ ++} ++#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)) */ ++ ++#define netif_set_real_num_tx_queues LINUX_BACKPORT(netif_set_real_num_tx_queues) ++extern int netif_set_real_num_tx_queues(struct net_device *dev, ++ unsigned int txq); ++ ++/* mask irq_set_affinity_hint as RHEL6 backports this */ ++#define irq_set_affinity_hint(a,b) compat_irq_set_affinity_hint(a,b) ++/* ++ * We cannot backport this guy as the IRQ data structure ++ * was modified in the kernel itself to support this. We ++ * treat the system as uni-processor in this case. ++ */ ++static inline int irq_set_affinity_hint(unsigned int irq, ++ const struct cpumask *m) ++{ ++ return -EINVAL; ++} ++ ++static inline wait_queue_head_t *sk_sleep(struct sock *sk) ++{ ++ return sk->sk_sleep; ++} ++ ++#define sdio_writeb_readb(func, write_byte, addr, err_ret) sdio_readb(func, addr, err_ret) ++ ++#define hex_to_bin LINUX_BACKPORT(hex_to_bin) ++int hex_to_bin(char ch); ++ ++#define noop_llseek LINUX_BACKPORT(noop_llseek) ++extern loff_t noop_llseek(struct file *file, loff_t offset, int origin); ++ ++#define pm_qos_request(_qos) pm_qos_requirement(_qos) ++ ++/* mask usb_pipe_endpoint as RHEL6 backports this */ ++#define usb_pipe_endpoint(a,b) compat_usb_pipe_endpoint(a,b) ++ ++static inline struct usb_host_endpoint * ++usb_pipe_endpoint(struct usb_device *dev, unsigned int pipe) ++{ ++ struct usb_host_endpoint **eps; ++ eps = usb_pipein(pipe) ? dev->ep_in : dev->ep_out; ++ return eps[usb_pipeendpoint(pipe)]; ++} ++ ++#define simple_write_to_buffer LINUX_BACKPORT(simple_write_to_buffer) ++extern ssize_t simple_write_to_buffer(void *to, size_t available, loff_t *ppos, ++ const void __user *from, size_t count); ++ ++#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35)) */ ++ ++#endif /* LINUX_26_35_COMPAT_H */ diff --cc compat/include/linux/compat-2.6.36.h index 000000000000,000000000000..d90b84f674c4 new file mode 100644 --- /dev/null +++ b/compat/include/linux/compat-2.6.36.h @@@ -1,0 -1,0 +1,217 @@@ ++#ifndef LINUX_26_36_COMPAT_H ++#define LINUX_26_36_COMPAT_H ++ ++#include ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36)) ++ ++#include ++#include ++#include ++#include ++#include ++ ++#define kparam_block_sysfs_write(a) ++#define kparam_unblock_sysfs_write(a) ++ ++/* mask va_format as RHEL6 backports this */ ++#define va_format compat_va_format ++ ++struct va_format { ++ const char *fmt; ++ va_list *va; ++}; ++ ++#define device_rename(dev, new_name) device_rename(dev, (char *)new_name) ++ ++#ifdef CONFIG_COMPAT_USB_URB_THREAD_FIX ++#define usb_scuttle_anchored_urbs LINUX_BACKPORT(usb_scuttle_anchored_urbs) ++#define usb_get_from_anchor LINUX_BACKPORT(usb_get_from_anchor) ++#define usb_unlink_anchored_urbs LINUX_BACKPORT(usb_unlink_anchored_urbs) ++ ++extern void usb_unlink_anchored_urbs(struct usb_anchor *anchor); ++extern struct urb *usb_get_from_anchor(struct usb_anchor *anchor); ++extern void usb_scuttle_anchored_urbs(struct usb_anchor *anchor); ++#endif ++ ++/** ++ * pcmcia_read_config_byte() - read a byte from a card configuration register ++ * ++ * pcmcia_read_config_byte() reads a byte from a configuration register in ++ * attribute memory. ++ */ ++static inline int pcmcia_read_config_byte(struct pcmcia_device *p_dev, off_t where, u8 *val) ++{ ++ int ret; ++ conf_reg_t reg = { 0, CS_READ, where, 0 }; ++ ret = pcmcia_access_configuration_register(p_dev, ®); ++ *val = reg.Value; ++ return ret; ++} ++ ++/** ++ * pcmcia_write_config_byte() - write a byte to a card configuration register ++ * ++ * pcmcia_write_config_byte() writes a byte to a configuration register in ++ * attribute memory. ++ */ ++static inline int pcmcia_write_config_byte(struct pcmcia_device *p_dev, off_t where, u8 val) ++{ ++ conf_reg_t reg = { 0, CS_WRITE, where, val }; ++ return pcmcia_access_configuration_register(p_dev, ®); ++} ++ ++struct pm_qos_request_list { ++ u32 qos; ++ void *request; ++}; ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35)) ++ ++#define pm_qos_add_request(_req, _class, _value) do { \ ++ (_req)->request = #_req; \ ++ (_req)->qos = _class; \ ++ pm_qos_add_requirement((_class), (_req)->request, (_value)); \ ++ } while(0) ++ ++#define pm_qos_update_request(_req, _value) \ ++ pm_qos_update_requirement((_req)->qos, (_req)->request, (_value)) ++ ++#define pm_qos_remove_request(_req) \ ++ pm_qos_remove_requirement((_req)->qos, (_req)->request) ++ ++#else ++ ++#define pm_qos_add_request(_req, _class, _value) do { \ ++ (_req)->request = pm_qos_add_request((_class), (_value)); \ ++ } while (0) ++ ++#define pm_qos_update_request(_req, _value) \ ++ pm_qos_update_request((_req)->request, (_value)) ++ ++#define pm_qos_remove_request(_req) \ ++ pm_qos_remove_request((_req)->request) ++ ++#endif ++ ++/* ++ * Dummy printk for disabled debugging statements to use whilst maintaining ++ * gcc's format and side-effect checking. ++ */ ++/* mask no_printk as RHEL6 backports this */ ++#define no_printk(a, ...) compat_no_printk(a, ##__VA_ARGS__) ++static inline __attribute__ ((format (printf, 1, 2))) ++int no_printk(const char *s, ...) { return 0; } ++ ++#ifndef alloc_workqueue ++#define alloc_workqueue(name, flags, max_active) __create_workqueue(name, flags, max_active, 0) ++#endif ++ ++#define EXTPROC 0200000 ++#define TIOCPKT_IOCTL 64 ++ ++static inline void tty_lock(void) __acquires(kernel_lock) ++{ ++#ifdef CONFIG_LOCK_KERNEL ++ /* kernel_locked is 1 for !CONFIG_LOCK_KERNEL */ ++ WARN_ON(kernel_locked()); ++#endif ++ lock_kernel(); ++} ++static inline void tty_unlock(void) __releases(kernel_lock) ++{ ++ unlock_kernel(); ++} ++#define tty_locked() (kernel_locked()) ++ ++#define usleep_range(_min, _max) msleep((_max) / 1000) ++ ++#define __rcu ++ ++static inline void pm_wakeup_event(struct device *dev, unsigned int msec) {} ++ ++static inline bool skb_defer_rx_timestamp(struct sk_buff *skb) ++{ ++ return false; ++} ++ ++static inline void skb_tx_timestamp(struct sk_buff *skb) ++{ ++} ++ ++/* ++ * System-wide workqueues which are always present. ++ * ++ * system_wq is the one used by schedule[_delayed]_work[_on](). ++ * Multi-CPU multi-threaded. There are users which expect relatively ++ * short queue flush time. Don't queue works which can run for too ++ * long. ++ * ++ * system_long_wq is similar to system_wq but may host long running ++ * works. Queue flushing might take relatively long. ++ * ++ * system_nrt_wq is non-reentrant and guarantees that any given work ++ * item is never executed in parallel by multiple CPUs. Queue ++ * flushing might take relatively long. ++ */ ++#define system_wq LINUX_BACKPORT(system_wq) ++extern struct workqueue_struct *system_wq; ++#define system_long_wq LINUX_BACKPORT(system_long_wq) ++extern struct workqueue_struct *system_long_wq; ++#define system_nrt_wq LINUX_BACKPORT(system_nrt_wq) ++extern struct workqueue_struct *system_nrt_wq; ++ ++void backport_system_workqueue_create(void); ++void backport_system_workqueue_destroy(void); ++ ++#define schedule_work LINUX_BACKPORT(schedule_work) ++int schedule_work(struct work_struct *work); ++#define schedule_work_on LINUX_BACKPORT(schedule_work_on) ++int schedule_work_on(int cpu, struct work_struct *work); ++#define compat_schedule_delayed_work LINUX_BACKPORT(compat_schedule_delayed_work) ++int schedule_delayed_work(struct delayed_work *dwork, ++ unsigned long delay); ++#define compat_schedule_delayed_work_on LINUX_BACKPORT(compat_schedule_delayed_work_on) ++int schedule_delayed_work_on(int cpu, ++ struct delayed_work *dwork, ++ unsigned long delay); ++#define flush_scheduled_work LINUX_BACKPORT(flush_scheduled_work) ++void flush_scheduled_work(void); ++ ++enum { ++ /* bit mask for work_busy() return values */ ++ WORK_BUSY_PENDING = 1 << 0, ++ WORK_BUSY_RUNNING = 1 << 1, ++}; ++ ++#define work_busy LINUX_BACKPORT(work_busy) ++extern unsigned int work_busy(struct work_struct *work); ++ ++#define br_port_exists(dev) (dev->br_port) ++ ++#else ++ ++static inline void backport_system_workqueue_create(void) ++{ ++} ++ ++static inline void backport_system_workqueue_destroy(void) ++{ ++} ++ ++/* ++ * This is not part of The 2.6.37 kernel yet but we ++ * we use it to optimize the backport code we ++ * need to implement. Instead of using ifdefs ++ * to check what version of the check we use ++ * we just replace all checks on current code ++ * with this. I'll submit this upstream too, that ++ * way all we'd have to do is to implement this ++ * for older kernels, then we would not have to ++ * edit the upstrema code for backport efforts. ++ */ ++#define br_port_exists(dev) (dev->priv_flags & IFF_BRIDGE_PORT) ++ ++#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36)) */ ++ ++#endif /* LINUX_26_36_COMPAT_H */ diff --cc compat/include/linux/compat-2.6.37.h index 000000000000,000000000000..317ae6fe88d4 new file mode 100644 --- /dev/null +++ b/compat/include/linux/compat-2.6.37.h @@@ -1,0 -1,0 +1,182 @@@ ++#ifndef LINUX_26_37_COMPAT_H ++#define LINUX_26_37_COMPAT_H ++ ++#include ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,37)) ++ ++#include ++#include ++#include ++#include ++#include ++ ++#ifdef CONFIG_RPS ++extern int netif_set_real_num_rx_queues(struct net_device *dev, ++ unsigned int rxq); ++#else ++static inline int netif_set_real_num_rx_queues(struct net_device *dev, ++ unsigned int rxq) ++{ ++ return 0; ++} ++#endif ++ ++static inline int proto_ports_offset(int proto) ++{ ++ switch (proto) { ++ case IPPROTO_TCP: ++ case IPPROTO_UDP: ++ case IPPROTO_DCCP: ++ case IPPROTO_ESP: /* SPI */ ++ case IPPROTO_SCTP: ++ case IPPROTO_UDPLITE: ++ return 0; ++ case IPPROTO_AH: /* SPI */ ++ return 4; ++ default: ++ return -EINVAL; ++ } ++} ++ ++#define SDIO_CLASS_BT_AMP 0x09 /* Type-A Bluetooth AMP interface */ ++ ++#define net_ns_type_operations LINUX_BACKPORT(net_ns_type_operations) ++extern struct kobj_ns_type_operations net_ns_type_operations; ++ ++/* mask skb_checksum_none_assert as RHEL6 backports this */ ++#define skb_checksum_none_assert(a) compat_skb_checksum_none_assert(a) ++ ++/** ++ * skb_checksum_none_assert - make sure skb ip_summed is CHECKSUM_NONE ++ * @skb: skb to check ++ * ++ * fresh skbs have their ip_summed set to CHECKSUM_NONE. ++ * Instead of forcing ip_summed to CHECKSUM_NONE, we can ++ * use this helper, to document places where we make this assertion. ++ */ ++static inline void skb_checksum_none_assert(struct sk_buff *skb) ++{ ++#ifdef DEBUG ++ BUG_ON(skb->ip_summed != CHECKSUM_NONE); ++#endif ++} ++ ++#define pcmcia_enable_device(link) pcmcia_request_configuration(link, &link->conf) ++ ++#include ++ ++struct compat_genl_info { ++ struct genl_info *info; ++ ++ u32 snd_seq; ++ u32 snd_pid; ++ struct genlmsghdr *genlhdr; ++ struct nlattr **attrs; ++ void *user_ptr[2]; ++}; ++#define genl_info compat_genl_info ++ ++struct compat_genl_ops { ++ struct genl_ops ops; ++ ++ u8 cmd; ++ u8 internal_flags; ++ unsigned int flags; ++ const struct nla_policy *policy; ++ ++ int (*doit)(struct sk_buff *skb, struct genl_info *info); ++ int (*dumpit)(struct sk_buff *skb, struct netlink_callback *cb); ++ int (*done)(struct netlink_callback *cb); ++}; ++#define genl_ops compat_genl_ops ++ ++struct compat_genl_family { ++ struct genl_family family; ++ ++ struct list_head list; ++ ++ unsigned int id, hdrsize, version, maxattr; ++ const char *name; ++ bool netnsok; ++ ++ struct nlattr **attrbuf; ++ ++ int (*pre_doit)(struct genl_ops *ops, struct sk_buff *skb, ++ struct genl_info *info); ++ ++ void (*post_doit)(struct genl_ops *ops, struct sk_buff *skb, ++ struct genl_info *info); ++}; ++ ++#define genl_family compat_genl_family ++ ++#define genl_register_family_with_ops compat_genl_register_family_with_ops ++ ++int genl_register_family_with_ops(struct genl_family *family, ++ struct genl_ops *ops, size_t n_ops); ++ ++#define genl_unregister_family compat_genl_unregister_family ++ ++int genl_unregister_family(struct genl_family *family); ++ ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32)) ++#define genl_info_net(_info) genl_info_net((_info)->info) ++#endif ++ ++#define genlmsg_reply(_msg, _info) genlmsg_reply(_msg, (_info)->info) ++#define genlmsg_put(_skb, _pid, _seq, _fam, _flags, _cmd) genlmsg_put(_skb, _pid, _seq, &(_fam)->family, _flags, _cmd) ++#define genl_register_mc_group(_fam, _grp) genl_register_mc_group(&(_fam)->family, _grp) ++#define genl_unregister_mc_group(_fam, _grp) genl_unregister_mc_group(&(_fam)->family, _grp) ++ ++ ++extern void led_blink_set(struct led_classdev *led_cdev, ++ unsigned long *delay_on, ++ unsigned long *delay_off); ++ ++#define led_classdev_unregister compat_led_classdev_unregister ++extern void compat_led_classdev_unregister(struct led_classdev *led_cdev); ++ ++#define led_brightness_set compat_led_brightness_set ++extern void compat_led_brightness_set(struct led_classdev *led_cdev, ++ enum led_brightness brightness); ++ ++#define alloc_ordered_workqueue(name, flags) create_singlethread_workqueue(name) ++ ++#define netdev_refcnt_read(a) atomic_read(&a->refcnt) ++ ++#define vzalloc LINUX_BACKPORT(vzalloc) ++extern void *vzalloc(unsigned long size); ++ ++#define rtnl_dereference(p) \ ++ rcu_dereference_protected(p, lockdep_rtnl_is_held()) ++ ++/** ++ * RCU_INIT_POINTER() - initialize an RCU protected pointer ++ * ++ * Initialize an RCU-protected pointer in such a way to avoid RCU-lockdep ++ * splats. ++ */ ++#define RCU_INIT_POINTER(p, v) \ ++ p = (typeof(*v) __force __rcu *)(v) ++ ++static inline bool skb_has_frag_list(const struct sk_buff *skb) ++{ ++ return skb_shinfo(skb)->frag_list != NULL; ++} ++ ++/** ++ * backport: ++ * ++ * commit 67bdbffd696f29a0b68aa8daa285783a06651583 ++ * Author: Arnd Bergmann ++ * Date: Thu Feb 25 16:55:13 2010 +0100 ++ * ++ * rculist: avoid __rcu annotations ++ */ ++#define hlist_first_rcu(head) (*((struct hlist_node __rcu **)(&(head)->first))) ++#define hlist_next_rcu(node) (*((struct hlist_node __rcu **)(&(node)->next))) ++ ++#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,37)) */ ++ ++#endif /* LINUX_26_37_COMPAT_H */ diff --cc compat/include/linux/compat-2.6.38.h index 000000000000,000000000000..58ec64e5675b new file mode 100644 --- /dev/null +++ b/compat/include/linux/compat-2.6.38.h @@@ -1,0 -1,0 +1,194 @@@ ++#ifndef LINUX_26_38_COMPAT_H ++#define LINUX_26_38_COMPAT_H ++ ++#include ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38)) ++ ++#include ++#include ++#include ++#include ++ ++#define PCI_MSIX_ENTRY_CTRL_MASKBIT 1 ++ ++#define alloc_etherdev_mqs(sizeof_priv, tx_q, rx_q) alloc_etherdev_mq(sizeof_priv, tx_q) ++ ++/* MSI-X entry's format */ ++#define PCI_MSIX_ENTRY_SIZE 16 ++#define PCI_MSIX_ENTRY_LOWER_ADDR 0 ++#define PCI_MSIX_ENTRY_UPPER_ADDR 4 ++#define PCI_MSIX_ENTRY_DATA 8 ++#define PCI_MSIX_ENTRY_VECTOR_CTRL 12 ++ ++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,30)) ++static inline void bstats_update(struct gnet_stats_basic_packed *bstats, ++ const struct sk_buff *skb) ++{ ++ bstats->bytes += qdisc_pkt_len((struct sk_buff *) skb); ++ bstats->packets += skb_is_gso(skb) ? skb_shinfo(skb)->gso_segs : 1; ++} ++static inline void qdisc_bstats_update(struct Qdisc *sch, ++ const struct sk_buff *skb) ++{ ++ bstats_update(&sch->bstats, skb); ++} ++#else ++/* ++ * kernels <= 2.6.30 do not pass a const skb to qdisc_pkt_len, and ++ * gnet_stats_basic_packed did not exist (see c1a8f1f1c8) ++ */ ++static inline void bstats_update(struct gnet_stats_basic *bstats, ++ struct sk_buff *skb) ++{ ++ bstats->bytes += qdisc_pkt_len(skb); ++ bstats->packets += skb_is_gso(skb) ? skb_shinfo(skb)->gso_segs : 1; ++} ++static inline void qdisc_bstats_update(struct Qdisc *sch, ++ struct sk_buff *skb) ++{ ++ bstats_update(&sch->bstats, skb); ++} ++#endif ++ ++ ++/* rename member in struct mmc_host in include/linux/mmc/host.h */ ++#define max_segs max_hw_segs ++ ++ ++/* Exponentially weighted moving average (EWMA) */ ++ ++/* For more documentation see lib/average.c */ ++ ++struct ewma { ++ unsigned long internal; ++ unsigned long factor; ++ unsigned long weight; ++}; ++ ++#define ewma_init LINUX_BACKPORT(ewma_init) ++extern void ewma_init(struct ewma *avg, unsigned long factor, ++ unsigned long weight); ++ ++#define ewma_add LINUX_BACKPORT(ewma_add) ++extern struct ewma *ewma_add(struct ewma *avg, unsigned long val); ++ ++#define ewma_read LINUX_BACKPORT(ewma_read) ++/** ++ * ewma_read() - Get average value ++ * @avg: Average structure ++ * ++ * Returns the average value held in @avg. ++ */ ++static inline unsigned long ewma_read(const struct ewma *avg) ++{ ++ return DIV_ROUND_CLOSEST(avg->internal, avg->factor); ++} ++ ++#define pr_warn pr_warning ++#define create_freezable_workqueue create_freezeable_workqueue ++ ++static inline int skb_checksum_start_offset(const struct sk_buff *skb) ++{ ++ return skb->csum_start - skb_headroom(skb); ++} ++ ++/* from include/linux/printk.h */ ++#define pr_emerg_once(fmt, ...) \ ++ printk_once(KERN_EMERG pr_fmt(fmt), ##__VA_ARGS__) ++#define pr_alert_once(fmt, ...) \ ++ printk_once(KERN_ALERT pr_fmt(fmt), ##__VA_ARGS__) ++#define pr_crit_once(fmt, ...) \ ++ printk_once(KERN_CRIT pr_fmt(fmt), ##__VA_ARGS__) ++#define pr_err_once(fmt, ...) \ ++ printk_once(KERN_ERR pr_fmt(fmt), ##__VA_ARGS__) ++#define pr_warn_once(fmt, ...) \ ++ printk_once(KERN_WARNING pr_fmt(fmt), ##__VA_ARGS__) ++#define pr_notice_once(fmt, ...) \ ++ printk_once(KERN_NOTICE pr_fmt(fmt), ##__VA_ARGS__) ++#define pr_info_once(fmt, ...) \ ++ printk_once(KERN_INFO pr_fmt(fmt), ##__VA_ARGS__) ++#define pr_cont_once(fmt, ...) \ ++ printk_once(KERN_CONT pr_fmt(fmt), ##__VA_ARGS__) ++#if defined(DEBUG) ++#define pr_debug_once(fmt, ...) \ ++ printk_once(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__) ++#else ++#define pr_debug_once(fmt, ...) \ ++ no_printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__) ++#endif ++ ++/* include/linux/netdevice.h */ ++#define alloc_netdev_mqs(sizeof_priv, name, setup, txqs, rxqs) \ ++ alloc_netdev_mq(sizeof_priv, name, setup, \ ++ max_t(unsigned int, txqs, rxqs)) ++ ++#define ETH_P_LINK_CTL 0x886c /* HPNA, wlan link local tunnel */ ++ ++/** ++ * is_unicast_ether_addr - Determine if the Ethernet address is unicast ++ * @addr: Pointer to a six-byte array containing the Ethernet address ++ * ++ * Return true if the address is a unicast address. ++ */ ++static inline int is_unicast_ether_addr(const u8 *addr) ++{ ++ return !is_multicast_ether_addr(addr); ++} ++ ++/* Backport of: ++ * ++ * commit 7ef88ad561457c0346355dfd1f53e503ddfde719 ++ * Author: Rusty Russell ++ * Date: Mon Jan 24 14:45:10 2011 -0600 ++ * ++ * BUILD_BUG_ON: make it handle more cases ++ */ ++#undef BUILD_BUG_ON ++/** ++ * BUILD_BUG_ON - break compile if a condition is true. ++ * @condition: the condition which the compiler should know is false. ++ * ++ * If you have some code which relies on certain constants being equal, or ++ * other compile-time-evaluated condition, you should use BUILD_BUG_ON to ++ * detect if someone changes it. ++ * ++ * The implementation uses gcc's reluctance to create a negative array, but ++ * gcc (as of 4.4) only emits that error for obvious cases (eg. not arguments ++ * to inline functions). So as a fallback we use the optimizer; if it can't ++ * prove the condition is false, it will cause a link error on the undefined ++ * "__build_bug_on_failed". This error message can be harder to track down ++ * though, hence the two different methods. ++ */ ++#ifndef __OPTIMIZE__ ++#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)])) ++#else ++extern int __build_bug_on_failed; ++#define BUILD_BUG_ON(condition) \ ++ do { \ ++ ((void)sizeof(char[1 - 2*!!(condition)])); \ ++ if (condition) __build_bug_on_failed = 1; \ ++ } while(0) ++#endif ++ ++/* Backport of: ++ * ++ * commit e159489baa717dbae70f9903770a6a4990865887 ++ * Author: Tejun Heo ++ * Date: Sun Jan 9 23:32:15 2011 +0100 ++ * ++ * workqueue: relax lockdep annotation on flush_work() ++ */ ++#ifdef CONFIG_DEBUG_LOCK_ALLOC ++# ifdef CONFIG_PROVE_LOCKING ++# define lock_map_acquire_read(l) lock_acquire(l, 0, 0, 2, 2, NULL, _THIS_IP_) ++# else ++# define lock_map_acquire_read(l) lock_acquire(l, 0, 0, 2, 1, NULL, _THIS_IP_) ++# endif ++#else ++# define lock_map_acquire_read(l) do { } while (0) ++#endif ++ ++#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38)) */ ++ ++#endif /* LINUX_26_38_COMPAT_H */ diff --cc compat/include/linux/compat-2.6.39.h index 000000000000,000000000000..e9a2eba819e7 new file mode 100644 --- /dev/null +++ b/compat/include/linux/compat-2.6.39.h @@@ -1,0 -1,0 +1,181 @@@ ++#ifndef LINUX_26_39_COMPAT_H ++#define LINUX_26_39_COMPAT_H ++ ++#include ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,39)) ++ ++#include ++#include ++#include ++#include ++ ++static inline int __must_check PTR_RET(const void *ptr) ++{ ++ if (IS_ERR(ptr)) ++ return PTR_ERR(ptr); ++ else ++ return 0; ++} ++ ++#define NETIF_F_RXCSUM 0 ++ ++#define tiocmget(tty) tiocmget(tty, NULL) ++#define tiocmset(tty, set, clear) tiocmset(tty, NULL, set, clear) ++ ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)) ++#define tty_set_termios LINUX_BACKPORT(tty_set_termios) ++extern int tty_set_termios(struct tty_struct *tty, struct ktermios *kt); ++#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)) */ ++ ++static inline int irq_set_irq_wake(unsigned int irq, unsigned int on) ++{ ++ return set_irq_wake(irq, on); ++} ++static inline int irq_set_chip(unsigned int irq, struct irq_chip *chip) ++{ ++ return set_irq_chip(irq, chip); ++} ++static inline int irq_set_handler_data(unsigned int irq, void *data) ++{ ++ return set_irq_data(irq, data); ++} ++static inline int irq_set_chip_data(unsigned int irq, void *data) ++{ ++ return set_irq_chip_data(irq, data); ++} ++static inline int irq_set_irq_type(unsigned int irq, unsigned int type) ++{ ++ return set_irq_type(irq, type); ++} ++static inline int irq_set_msi_desc(unsigned int irq, struct msi_desc *entry) ++{ ++ return set_irq_msi(irq, entry); ++} ++static inline struct irq_chip *irq_get_chip(unsigned int irq) ++{ ++ return get_irq_chip(irq); ++} ++static inline void *irq_get_chip_data(unsigned int irq) ++{ ++ return get_irq_chip_data(irq); ++} ++static inline void *irq_get_handler_data(unsigned int irq) ++{ ++ return get_irq_data(irq); ++} ++ ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) ++static inline void *irq_data_get_irq_handler_data(struct irq_data *d) ++{ ++ return irq_data_get_irq_data(d); ++} ++#endif ++ ++static inline struct msi_desc *irq_get_msi_desc(unsigned int irq) ++{ ++ return get_irq_msi(irq); ++} ++ ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,25)) ++static inline void irq_set_noprobe(unsigned int irq) ++{ ++ set_irq_noprobe(irq); ++} ++static inline void irq_set_probe(unsigned int irq) ++{ ++ set_irq_probe(irq); ++} ++#endif ++ ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)) ++static inline struct irq_chip *irq_desc_get_chip(struct irq_desc *desc) ++{ ++ return get_irq_desc_chip(desc); ++} ++static inline void *irq_desc_get_handler_data(struct irq_desc *desc) ++{ ++ return get_irq_desc_data(desc); ++} ++ ++static inline void *irq_desc_get_chip_data(struct irq_desc *desc) ++{ ++ return get_irq_desc_chip_data(desc); ++} ++ ++static inline struct msi_desc *irq_desc_get_msi_desc(struct irq_desc *desc) ++{ ++ return get_irq_desc_msi(desc); ++} ++#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)) */ ++ ++/* ++ * kstrto* was included in kernel 2.6.38.4 and causes conflicts with the ++ * version included in compat-drivers. We use strict_strtol to check if ++ * kstrto* is already available. ++ */ ++#ifndef strict_strtoull ++/* Internal, do not use. */ ++int __must_check _kstrtoul(const char *s, unsigned int base, unsigned long *res); ++int __must_check _kstrtol(const char *s, unsigned int base, long *res); ++ ++int __must_check kstrtoull(const char *s, unsigned int base, unsigned long long *res); ++int __must_check kstrtoll(const char *s, unsigned int base, long long *res); ++static inline int __must_check kstrtoul(const char *s, unsigned int base, unsigned long *res) ++{ ++ /* ++ * We want to shortcut function call, but ++ * __builtin_types_compatible_p(unsigned long, unsigned long long) = 0. ++ */ ++ if (sizeof(unsigned long) == sizeof(unsigned long long) && ++ __alignof__(unsigned long) == __alignof__(unsigned long long)) ++ return kstrtoull(s, base, (unsigned long long *)res); ++ else ++ return _kstrtoul(s, base, res); ++} ++ ++static inline int __must_check kstrtol(const char *s, unsigned int base, long *res) ++{ ++ /* ++ * We want to shortcut function call, but ++ * __builtin_types_compatible_p(long, long long) = 0. ++ */ ++ if (sizeof(long) == sizeof(long long) && ++ __alignof__(long) == __alignof__(long long)) ++ return kstrtoll(s, base, (long long *)res); ++ else ++ return _kstrtol(s, base, res); ++} ++ ++int __must_check kstrtouint(const char *s, unsigned int base, unsigned int *res); ++int __must_check kstrtoint(const char *s, unsigned int base, int *res); ++ ++static inline int __must_check kstrtou64(const char *s, unsigned int base, u64 *res) ++{ ++ return kstrtoull(s, base, res); ++} ++ ++static inline int __must_check kstrtos64(const char *s, unsigned int base, s64 *res) ++{ ++ return kstrtoll(s, base, res); ++} ++ ++static inline int __must_check kstrtou32(const char *s, unsigned int base, u32 *res) ++{ ++ return kstrtouint(s, base, res); ++} ++ ++static inline int __must_check kstrtos32(const char *s, unsigned int base, s32 *res) ++{ ++ return kstrtoint(s, base, res); ++} ++ ++int __must_check kstrtou16(const char *s, unsigned int base, u16 *res); ++int __must_check kstrtos16(const char *s, unsigned int base, s16 *res); ++int __must_check kstrtou8(const char *s, unsigned int base, u8 *res); ++int __must_check kstrtos8(const char *s, unsigned int base, s8 *res); ++#endif /* ifndef strict_strtol */ ++ ++#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,39)) */ ++ ++#endif /* LINUX_26_39_COMPAT_H */ diff --cc compat/include/linux/compat-2.6.h index 000000000000,000000000000..1e9effb70442 new file mode 100644 --- /dev/null +++ b/compat/include/linux/compat-2.6.h @@@ -1,0 -1,0 +1,79 @@@ ++#ifndef LINUX_26_COMPAT_H ++#define LINUX_26_COMPAT_H ++ ++#ifndef __ASSEMBLY__ ++ ++#define LINUX_BACKPORT(__sym) backport_ ##__sym ++ ++#include ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,1,0)) ++#include ++#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,33)) ++#include ++#else ++#include ++#endif ++#include ++#include ++#include ++ ++/* ++ * The define overwriting module_init is based on the original module_init ++ * which looks like this: ++ * #define module_init(initfn) \ ++ * static inline initcall_t __inittest(void) \ ++ * { return initfn; } \ ++ * int init_module(void) __attribute__((alias(#initfn))); ++ * ++ * To the call to the initfn we added the symbol dependency on compat ++ * to make sure that compat.ko gets loaded for any compat modules. ++ */ ++void backport_dependency_symbol(void); ++ ++#undef module_init ++#define module_init(initfn) \ ++ static int __init __init_backport(void) \ ++ { \ ++ backport_dependency_symbol(); \ ++ return initfn(); \ ++ } \ ++ int init_module(void) __attribute__((alias("__init_backport"))); ++ ++/* ++ * Each compat file represents compatibility code for new kernel ++ * code introduced for *that* kernel revision. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#endif /* __ASSEMBLY__ */ ++ ++#endif /* LINUX_26_COMPAT_H */ diff --cc compat/include/linux/compat-3.0.h index 000000000000,000000000000..7fcd763a84da new file mode 100644 --- /dev/null +++ b/compat/include/linux/compat-3.0.h @@@ -1,0 -1,0 +1,162 @@@ ++#ifndef LINUX_3_0_COMPAT_H ++#define LINUX_3_0_COMPAT_H ++ ++#include ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0)) ++ ++#include ++ ++/* This pulls-in a lot of non-exported symbol backports ++ * on kernels older than 2.6.32. There's no harm for not ++ * making this available on kernels < 2.6.32. */ ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32)) ++#include ++ ++/* This backports the 2nd part of: ++ * ++ * commit d9d90e5eb70e09903dadff42099b6c948f814050 ++ * Author: Hugh Dickins ++ * Date: Mon Jun 27 16:18:04 2011 -0700 ++ * ++ * tmpfs: add shmem_read_mapping_page_gfp ++ * ++ * First part is in compat-3.0.c. ++ */ ++#define shmem_read_mapping_page_gfp LINUX_BACKPORT(shmem_read_mapping_page_gfp) ++extern struct page *shmem_read_mapping_page_gfp(struct address_space *mapping, ++ pgoff_t index, gfp_t gfp); ++ ++ ++#define shmem_read_mapping_page LINUX_BACKPORT(shmem_read_mapping_page) ++static inline struct page *shmem_read_mapping_page( ++ struct address_space *mapping, pgoff_t index) ++{ ++ return shmem_read_mapping_page_gfp(mapping, index, ++ mapping_gfp_mask(mapping)); ++} ++#endif ++ ++ ++/* ++ * since commit 1c5cae815d19ffe02bdfda1260949ef2b1806171 ++ * "net: call dev_alloc_name from register_netdevice" dev_alloc_name is ++ * called automatically. This is not implemented in older kernel ++ * versions so it will result in device wrong names. ++ */ ++static inline int register_netdevice_name(struct net_device *dev) ++{ ++ int err; ++ ++ if (strchr(dev->name, '%')) { ++ err = dev_alloc_name(dev, dev->name); ++ if (err < 0) ++ return err; ++ } ++ ++ return register_netdevice(dev); ++} ++ ++#define register_netdevice(dev) register_netdevice_name(dev) ++ ++/* BCMA core, see drivers/bcma/ */ ++#ifndef BCMA_CORE ++/* Broadcom's specific AMBA core, see drivers/bcma/ */ ++struct bcma_device_id { ++ __u16 manuf; ++ __u16 id; ++ __u8 rev; ++ __u8 class; ++}; ++#define BCMA_CORE(_manuf, _id, _rev, _class) \ ++ { .manuf = _manuf, .id = _id, .rev = _rev, .class = _class, } ++#define BCMA_CORETABLE_END \ ++ { 0, }, ++ ++#define BCMA_ANY_MANUF 0xFFFF ++#define BCMA_ANY_ID 0xFFFF ++#define BCMA_ANY_REV 0xFF ++#define BCMA_ANY_CLASS 0xFF ++#endif /* BCMA_CORE */ ++ ++#define mac_pton LINUX_BACKPORT(mac_pton) ++int mac_pton(const char *s, u8 *mac); ++ ++int __must_check kstrtoull_from_user(const char __user *s, size_t count, unsigned int base, unsigned long long *res); ++int __must_check kstrtoll_from_user(const char __user *s, size_t count, unsigned int base, long long *res); ++int __must_check kstrtoul_from_user(const char __user *s, size_t count, unsigned int base, unsigned long *res); ++int __must_check kstrtol_from_user(const char __user *s, size_t count, unsigned int base, long *res); ++int __must_check kstrtouint_from_user(const char __user *s, size_t count, unsigned int base, unsigned int *res); ++int __must_check kstrtoint_from_user(const char __user *s, size_t count, unsigned int base, int *res); ++int __must_check kstrtou16_from_user(const char __user *s, size_t count, unsigned int base, u16 *res); ++int __must_check kstrtos16_from_user(const char __user *s, size_t count, unsigned int base, s16 *res); ++int __must_check kstrtou8_from_user(const char __user *s, size_t count, unsigned int base, u8 *res); ++int __must_check kstrtos8_from_user(const char __user *s, size_t count, unsigned int base, s8 *res); ++ ++static inline int __must_check kstrtou64_from_user(const char __user *s, size_t count, unsigned int base, u64 *res) ++{ ++ return kstrtoull_from_user(s, count, base, res); ++} ++ ++static inline int __must_check kstrtos64_from_user(const char __user *s, size_t count, unsigned int base, s64 *res) ++{ ++ return kstrtoll_from_user(s, count, base, res); ++} ++ ++static inline int __must_check kstrtou32_from_user(const char __user *s, size_t count, unsigned int base, u32 *res) ++{ ++ return kstrtouint_from_user(s, count, base, res); ++} ++ ++static inline int __must_check kstrtos32_from_user(const char __user *s, size_t count, unsigned int base, s32 *res) ++{ ++ return kstrtoint_from_user(s, count, base, res); ++} ++ ++/* ++ * This adds a nested function everywhere kfree_rcu() was called. This ++ * function frees the memory and is given as a function to call_rcu(). ++ * The rcu callback could happen every time also after the module was ++ * unloaded and this will cause problems. ++ */ ++#define kfree_rcu(data, rcuhead) do { \ ++ void __kfree_rcu_fn(struct rcu_head *rcu_head) \ ++ { \ ++ void *___ptr; \ ++ ___ptr = container_of(rcu_head, typeof(*(data)), rcuhead);\ ++ kfree(___ptr); \ ++ } \ ++ call_rcu(&(data)->rcuhead, __kfree_rcu_fn); \ ++ } while (0) ++ ++#ifdef MODULE ++ ++/* ++ * The define overwriting module_exit is based on the original module_exit ++ * which looks like this: ++ * #define module_exit(exitfn) \ ++ * static inline exitcall_t __exittest(void) \ ++ * { return exitfn; } \ ++ * void cleanup_module(void) __attribute__((alias(#exitfn))); ++ * ++ * We replaced the call to the actual function exitfn() with a call to our ++ * function which calls the original exitfn() and then rcu_barrier() ++ * ++ * As a module will not be unloaded that ofter it should not have a big ++ * performance impact when rcu_barrier() is called on every module exit, ++ * also when no kfree_rcu() backport is used in that module. ++ */ ++#undef module_exit ++#define module_exit(exitfn) \ ++ static void __exit __exit_compat(void) \ ++ { \ ++ exitfn(); \ ++ rcu_barrier(); \ ++ } \ ++ void cleanup_module(void) __attribute__((alias("__exit_compat"))); ++ ++#endif ++ ++#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0)) */ ++ ++#endif /* LINUX_3_0_COMPAT_H */ diff --cc compat/include/linux/compat-3.1.h index 000000000000,000000000000..3e8be3361528 new file mode 100644 --- /dev/null +++ b/compat/include/linux/compat-3.1.h @@@ -1,0 -1,0 +1,108 @@@ ++#ifndef LINUX_3_1_COMPAT_H ++#define LINUX_3_1_COMPAT_H ++ ++#include ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,1,0)) ++ ++#include ++#include ++#include ++#include ++#include ++ ++#define HID_TYPE_USBNONE 2 ++ ++/* This backports: ++ * ++ * commit 36a26c69b4c70396ef569c3452690fba0c1dec08 ++ * Author: Nicholas Bellinger ++ * Date: Tue Jul 26 00:35:26 2011 -0700 ++ * ++ * kernel.h: Add DIV_ROUND_UP_ULL and DIV_ROUND_UP_SECTOR_T macro usage ++ */ ++ ++#define DIV_ROUND_UP_ULL(ll,d) \ ++ ({ unsigned long long _tmp = (ll)+(d)-1; do_div(_tmp, d); _tmp; }) ++ ++/* Backports 56f8a75c */ ++static inline bool ip_is_fragment(const struct iphdr *iph) ++{ ++ return (iph->frag_off & htons(IP_MF | IP_OFFSET)) != 0; ++} ++ ++/* mask __netdev_alloc_skb_ip_align as RHEL6 backports this */ ++#define __netdev_alloc_skb_ip_align(a,b,c) compat__netdev_alloc_skb_ip_align(a,b,c) ++static inline struct sk_buff *__netdev_alloc_skb_ip_align(struct net_device *dev, ++ unsigned int length, gfp_t gfp) ++{ ++ struct sk_buff *skb = __netdev_alloc_skb(dev, length + NET_IP_ALIGN, gfp); ++ ++ if (NET_IP_ALIGN && skb) ++ skb_reserve(skb, NET_IP_ALIGN); ++ return skb; ++} ++ ++#define genl_dump_check_consistent(cb, user_hdr, family) ++ ++/* ++ * IS_ENABLED(CONFIG_FOO) evaluates to 1 if CONFIG_FOO is set to 'y' or 'm', ++ * 0 otherwise. ++ * ++ */ ++#define IS_ENABLED(option) \ ++ (config_enabled(option) || config_enabled(option##_MODULE)) ++ ++#define IFF_TX_SKB_SHARING 0x10000 /* The interface supports sharing ++ * skbs on transmit */ ++ ++#define PCMCIA_DEVICE_MANF_CARD_PROD_ID3(manf, card, v3, vh3) { \ ++ .match_flags = PCMCIA_DEV_ID_MATCH_MANF_ID| \ ++ PCMCIA_DEV_ID_MATCH_CARD_ID| \ ++ PCMCIA_DEV_ID_MATCH_PROD_ID3, \ ++ .manf_id = (manf), \ ++ .card_id = (card), \ ++ .prod_id = { NULL, NULL, (v3), NULL }, \ ++ .prod_id_hash = { 0, 0, (vh3), 0 }, } ++ ++/* ++ * This has been defined in include/linux/security.h for some time, but was ++ * only given an EXPORT_SYMBOL for 3.1. Add a compat_* definition to avoid ++ * breaking the compile. ++ */ ++#define security_sk_clone(a, b) compat_security_sk_clone(a, b) ++ ++static inline void security_sk_clone(const struct sock *sk, struct sock *newsk) ++{ ++} ++ ++/* ++ * In many versions, several architectures do not seem to include an ++ * atomic64_t implementation, and do not include the software emulation from ++ * asm-generic/atomic64_t. ++ * Detect and handle this here. ++ */ ++#include ++ ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,31)) && !defined(ATOMIC64_INIT) && !defined(CONFIG_X86) && !((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,33)) && defined(CONFIG_ARM) && !defined(CONFIG_GENERIC_ATOMIC64)) ++#include ++#endif ++ ++#define ida_simple_get LINUX_BACKPORT(ida_simple_get) ++int ida_simple_get(struct ida *ida, unsigned int start, unsigned int end, ++ gfp_t gfp_mask); ++ ++#define ida_simple_remove LINUX_BACKPORT(ida_simple_remove) ++void ida_simple_remove(struct ida *ida, unsigned int id); ++ ++#ifdef CONFIG_CPU_FREQ ++#define cpufreq_quick_get_max LINUX_BACKPORT(cpufreq_quick_get_max) ++unsigned int cpufreq_quick_get_max(unsigned int cpu); ++#endif ++ ++struct watchdog_device { ++}; ++ ++#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(3,1,0)) */ ++ ++#endif /* LINUX_3_1_COMPAT_H */ diff --cc compat/include/linux/compat-3.10.h index 000000000000,000000000000..f972203b97c5 new file mode 100644 --- /dev/null +++ b/compat/include/linux/compat-3.10.h @@@ -1,0 -1,0 +1,97 @@@ ++#ifndef LINUX_3_10_COMPAT_H ++#define LINUX_3_10_COMPAT_H ++ ++#include ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0)) ++ ++#include ++#include ++#include ++ ++#define sg_page_iter_page LINUX_BACKPORT(sg_page_iter_page) ++/** ++ * sg_page_iter_page - get the current page held by the page iterator ++ * @piter: page iterator holding the page ++ */ ++static inline struct page *sg_page_iter_page(struct sg_page_iter *piter) ++{ ++ return nth_page(sg_page(piter->sg), piter->sg_pgoffset); ++} ++ ++#define sg_page_iter_dma_address LINUX_BACKPORT(sg_page_iter_dma_address) ++/** ++ * sg_page_iter_dma_address - get the dma address of the current page held by ++ * the page iterator. ++ * @piter: page iterator holding the page ++ */ ++static inline dma_addr_t sg_page_iter_dma_address(struct sg_page_iter *piter) ++{ ++ return sg_dma_address(piter->sg) + (piter->sg_pgoffset << PAGE_SHIFT); ++} ++ ++/* ++ * This is a linux-next data structure element collateral evolution, ++ * we use a wrapper to avoid #ifdef hell to backport it. This allows ++ * us to use a simple fb_info_skip_vt_switch() replacement for when ++ * the new data structure element is used. If coccinelle SmPL grammar ++ * could be used to express the transformation for us on compat-drivers ++ * it means we'd need to express it only once. If the structure element ++ * collateral evolution were to be used *at development* time and we'd ++ * have a way to express the inverse through SmPL we'd be able to ++ * backport this collateral evolution automatically for any new driver ++ * that used it. We'd use coccinelle to look for it and do the ++ * transformations for us based on the original commit (maybe SmPL ++ * would be listed on the commit log. ++ * ++ * We may need the LINUX_BACKPORT() call that adds the backport_ ++ * prefix for older kernels than 3.10 if distros decide to ++ * add this same static inline themselves (although unlikely). ++ */ ++#define fb_enable_skip_vt_switch LINUX_BACKPORT(fb_enable_skip_vt_switch) ++static inline void fb_enable_skip_vt_switch(struct fb_info *info) ++{ ++} ++ ++/** ++ * backport of: ++ * ++ * commit 6ed7ffddcf61f668114edb676417e5fb33773b59 ++ * Author: H Hartley Sweeten ++ * Date: Wed Mar 6 11:24:44 2013 -0700 ++ * ++ * pcmcia/ds.h: introduce helper for pcmcia_driver module boilerplate ++ */ ++ ++/** ++ * module_pcmcia_driver() - Helper macro for registering a pcmcia driver ++ * @__pcmcia_driver: pcmcia_driver struct ++ * ++ * Helper macro for pcmcia drivers which do not do anything special in module ++ * init/exit. This eliminates a lot of boilerplate. Each module may only use ++ * this macro once, and calling it replaces module_init() and module_exit(). ++ */ ++#define module_pcmcia_driver(__pcmcia_driver) \ ++ module_driver(__pcmcia_driver, pcmcia_register_driver, \ ++ pcmcia_unregister_driver) ++ ++#else /* kernel is >= 3.10 */ ++/* ++ * We'd delete this upstream ever got this, we use our ++ * backport_ prefix with LINUX_BACKPORT() so that if this ++ * does get upstream we would not have to add another ifdef ++ * here for the kernels in between v3.10.. up to the point ++ * the routine would have gotten added, we'd just delete this ++ * #else condition completely. If we didn't have this and ++ * say 3.12 added the static inline upstream, we'd have a ++ * clash on the backport for 3.12 as the routine would ++ * already be defined *but* we'd need it for 3.11. ++ */ ++#define fb_enable_skip_vt_switch LINUX_BACKPORT(fb_enable_skip_vt_switch) ++static inline void fb_enable_skip_vt_switch(struct fb_info *info) ++{ ++ info->skip_vt_switch = true; ++} ++#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0)) */ ++ ++#endif /* LINUX_3_10_COMPAT_H */ diff --cc compat/include/linux/compat-3.2.h index 000000000000,000000000000..982b9898d9ce new file mode 100644 --- /dev/null +++ b/compat/include/linux/compat-3.2.h @@@ -1,0 -1,0 +1,111 @@@ ++#ifndef LINUX_3_2_COMPAT_H ++#define LINUX_3_2_COMPAT_H ++ ++#include ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,2,0)) ++ ++#include ++#include ++#include ++ ++/* backports 07613b0b */ ++#if defined(CONFIG_DYNAMIC_DEBUG) ++#define DEFINE_DYNAMIC_DEBUG_METADATA(name, fmt) \ ++ static struct _ddebug __used __aligned(8) \ ++ __attribute__((section("__verbose"))) name = { \ ++ .modname = KBUILD_MODNAME, \ ++ .function = __func__, \ ++ .filename = __FILE__, \ ++ .format = (fmt), \ ++ .lineno = __LINE__, \ ++ .flags = _DPRINTK_FLAGS_DEFAULT, \ ++ .enabled = false, \ ++ } ++#endif /* defined(CONFIG_DYNAMIC_DEBUG) */ ++ ++/* backports b4625dab */ ++#define SDIO_CCCR_REV_3_00 3 /* CCCR/FBR Version 3.00 */ ++#define SDIO_SDIO_REV_3_00 4 /* SDIO Spec Version 3.00 */ ++ ++#define PMSG_IS_AUTO(msg) (((msg).event & PM_EVENT_AUTO) != 0) ++ ++/* mask skb_frag_page as RHEL6 backports this */ ++#define skb_frag_page(a) compat_skb_frag_page(a) ++ ++/** ++ * skb_frag_page - retrieve the page refered to by a paged fragment ++ * @frag: the paged fragment ++ * ++ * Returns the &struct page associated with @frag. ++ */ ++static inline struct page *skb_frag_page(const skb_frag_t *frag) ++{ ++ return frag->page; ++} ++ ++/* mask skb_frag_dma_map as RHEL6 backports this */ ++#define skb_frag_dma_map(a,b,c,d,e) compat_skb_frag_dma_map(a,b,c,d,e) ++ ++/** ++ * skb_frag_dma_map - maps a paged fragment via the DMA API ++ * @device: the device to map the fragment to ++ * @frag: the paged fragment to map ++ * @offset: the offset within the fragment (starting at the ++ * fragment's own offset) ++ * @size: the number of bytes to map ++ * @direction: the direction of the mapping (%PCI_DMA_*) ++ * ++ * Maps the page associated with @frag to @device. ++ */ ++static inline dma_addr_t skb_frag_dma_map(struct device *dev, ++ const skb_frag_t *frag, ++ size_t offset, size_t size, ++ enum dma_data_direction dir) ++{ ++ return dma_map_page(dev, skb_frag_page(frag), ++ frag->page_offset + offset, size, dir); ++} ++ ++#define ETH_P_TDLS 0x890D /* TDLS */ ++ ++/* mask skb_frag_size as RHEL6 backports this */ ++#define skb_frag_size(a) compat_skb_frag_size(a) ++ ++static inline unsigned int skb_frag_size(const skb_frag_t *frag) ++{ ++ return frag->size; ++} ++ ++static inline char *hex_byte_pack(char *buf, u8 byte) ++{ ++ *buf++ = hex_asc_hi(byte); ++ *buf++ = hex_asc_lo(byte); ++ return buf; ++} ++ ++/* module_platform_driver() - Helper macro for drivers that don't do ++ * anything special in module init/exit. This eliminates a lot of ++ * boilerplate. Each module may only use this macro once, and ++ * calling it replaces module_init() and module_exit() ++ */ ++#define module_platform_driver(__platform_driver) \ ++ module_driver(__platform_driver, platform_driver_register, \ ++ platform_driver_unregister) ++ ++static inline void *dma_zalloc_coherent(struct device *dev, size_t size, ++ dma_addr_t *dma_handle, gfp_t flag) ++{ ++ void *ret = dma_alloc_coherent(dev, size, dma_handle, flag); ++ if (ret) ++ memset(ret, 0, size); ++ return ret; ++} ++ ++#define __netdev_printk LINUX_BACKPORT(__netdev_printk) ++extern int __netdev_printk(const char *level, const struct net_device *dev, ++ struct va_format *vaf); ++ ++#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(3,2,0)) */ ++ ++#endif /* LINUX_3_2_COMPAT_H */ diff --cc compat/include/linux/compat-3.3.h index 000000000000,000000000000..ee4b7ce22bc2 new file mode 100644 --- /dev/null +++ b/compat/include/linux/compat-3.3.h @@@ -1,0 -1,0 +1,358 @@@ ++#ifndef LINUX_3_3_COMPAT_H ++#define LINUX_3_3_COMPAT_H ++ ++#include ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0)) ++ ++#include ++ ++/* include to override NL80211_FEATURE_SK_TX_STATUS */ ++#include ++#include ++#include ++#include ++#include ++ ++/* ++ * BQL was added as of v3.3 but some Linux distributions ++ * have backported BQL to their v3.2 kernels or older. To ++ * address this we assume that they also enabled CONFIG_BQL ++ * and test for that here and simply avoid adding the static ++ * inlines if it was defined ++ */ ++#ifndef CONFIG_BQL ++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,26)) ++static inline void netdev_tx_sent_queue(struct netdev_queue *dev_queue, ++ unsigned int bytes) ++{ ++} ++#endif ++ ++static inline void netdev_sent_queue(struct net_device *dev, unsigned int bytes) ++{ ++} ++ ++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,26)) ++static inline void netdev_tx_completed_queue(struct netdev_queue *dev_queue, ++ unsigned pkts, unsigned bytes) ++{ ++} ++#endif ++ ++static inline void netdev_completed_queue(struct net_device *dev, ++ unsigned pkts, unsigned bytes) ++{ ++} ++ ++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,26)) ++static inline void netdev_tx_reset_queue(struct netdev_queue *q) ++{ ++} ++#endif ++ ++static inline void netdev_reset_queue(struct net_device *dev_queue) ++{ ++} ++#endif /* CONFIG_BQL */ ++ ++/** ++ * ethtool_adv_to_mii_adv_t ++ * @ethadv: the ethtool advertisement settings ++ * ++ * A small helper function that translates ethtool advertisement ++ * settings to phy autonegotiation advertisements for the ++ * MII_ADVERTISE register. ++ */ ++static inline u32 ethtool_adv_to_mii_adv_t(u32 ethadv) ++{ ++ u32 result = 0; ++ ++ if (ethadv & ADVERTISED_10baseT_Half) ++ result |= ADVERTISE_10HALF; ++ if (ethadv & ADVERTISED_10baseT_Full) ++ result |= ADVERTISE_10FULL; ++ if (ethadv & ADVERTISED_100baseT_Half) ++ result |= ADVERTISE_100HALF; ++ if (ethadv & ADVERTISED_100baseT_Full) ++ result |= ADVERTISE_100FULL; ++ if (ethadv & ADVERTISED_Pause) ++ result |= ADVERTISE_PAUSE_CAP; ++ if (ethadv & ADVERTISED_Asym_Pause) ++ result |= ADVERTISE_PAUSE_ASYM; ++ ++ return result; ++} ++ ++/** ++ * mii_adv_to_ethtool_adv_t ++ * @adv: value of the MII_ADVERTISE register ++ * ++ * A small helper function that translates MII_ADVERTISE bits ++ * to ethtool advertisement settings. ++ */ ++static inline u32 mii_adv_to_ethtool_adv_t(u32 adv) ++{ ++ u32 result = 0; ++ ++ if (adv & ADVERTISE_10HALF) ++ result |= ADVERTISED_10baseT_Half; ++ if (adv & ADVERTISE_10FULL) ++ result |= ADVERTISED_10baseT_Full; ++ if (adv & ADVERTISE_100HALF) ++ result |= ADVERTISED_100baseT_Half; ++ if (adv & ADVERTISE_100FULL) ++ result |= ADVERTISED_100baseT_Full; ++ if (adv & ADVERTISE_PAUSE_CAP) ++ result |= ADVERTISED_Pause; ++ if (adv & ADVERTISE_PAUSE_ASYM) ++ result |= ADVERTISED_Asym_Pause; ++ ++ return result; ++} ++ ++/** ++ * ethtool_adv_to_mii_ctrl1000_t ++ * @ethadv: the ethtool advertisement settings ++ * ++ * A small helper function that translates ethtool advertisement ++ * settings to phy autonegotiation advertisements for the ++ * MII_CTRL1000 register when in 1000T mode. ++ */ ++static inline u32 ethtool_adv_to_mii_ctrl1000_t(u32 ethadv) ++{ ++ u32 result = 0; ++ ++ if (ethadv & ADVERTISED_1000baseT_Half) ++ result |= ADVERTISE_1000HALF; ++ if (ethadv & ADVERTISED_1000baseT_Full) ++ result |= ADVERTISE_1000FULL; ++ ++ return result; ++} ++ ++/** ++ * mii_ctrl1000_to_ethtool_adv_t ++ * @adv: value of the MII_CTRL1000 register ++ * ++ * A small helper function that translates MII_CTRL1000 ++ * bits, when in 1000Base-T mode, to ethtool ++ * advertisement settings. ++ */ ++static inline u32 mii_ctrl1000_to_ethtool_adv_t(u32 adv) ++{ ++ u32 result = 0; ++ ++ if (adv & ADVERTISE_1000HALF) ++ result |= ADVERTISED_1000baseT_Half; ++ if (adv & ADVERTISE_1000FULL) ++ result |= ADVERTISED_1000baseT_Full; ++ ++ return result; ++} ++ ++/** ++ * mii_lpa_to_ethtool_lpa_t ++ * @adv: value of the MII_LPA register ++ * ++ * A small helper function that translates MII_LPA ++ * bits, when in 1000Base-T mode, to ethtool ++ * LP advertisement settings. ++ */ ++static inline u32 mii_lpa_to_ethtool_lpa_t(u32 lpa) ++{ ++ u32 result = 0; ++ ++ if (lpa & LPA_LPACK) ++ result |= ADVERTISED_Autoneg; ++ ++ return result | mii_adv_to_ethtool_adv_t(lpa); ++} ++ ++/** ++ * mii_stat1000_to_ethtool_lpa_t ++ * @adv: value of the MII_STAT1000 register ++ * ++ * A small helper function that translates MII_STAT1000 ++ * bits, when in 1000Base-T mode, to ethtool ++ * advertisement settings. ++ */ ++static inline u32 mii_stat1000_to_ethtool_lpa_t(u32 lpa) ++{ ++ u32 result = 0; ++ ++ if (lpa & LPA_1000HALF) ++ result |= ADVERTISED_1000baseT_Half; ++ if (lpa & LPA_1000FULL) ++ result |= ADVERTISED_1000baseT_Full; ++ ++ return result; ++} ++ ++/** ++ * ethtool_adv_to_mii_adv_x ++ * @ethadv: the ethtool advertisement settings ++ * ++ * A small helper function that translates ethtool advertisement ++ * settings to phy autonegotiation advertisements for the ++ * MII_CTRL1000 register when in 1000Base-X mode. ++ */ ++static inline u32 ethtool_adv_to_mii_adv_x(u32 ethadv) ++{ ++ u32 result = 0; ++ ++ if (ethadv & ADVERTISED_1000baseT_Half) ++ result |= ADVERTISE_1000XHALF; ++ if (ethadv & ADVERTISED_1000baseT_Full) ++ result |= ADVERTISE_1000XFULL; ++ if (ethadv & ADVERTISED_Pause) ++ result |= ADVERTISE_1000XPAUSE; ++ if (ethadv & ADVERTISED_Asym_Pause) ++ result |= ADVERTISE_1000XPSE_ASYM; ++ ++ return result; ++} ++ ++/** ++ * mii_adv_to_ethtool_adv_x ++ * @adv: value of the MII_CTRL1000 register ++ * ++ * A small helper function that translates MII_CTRL1000 ++ * bits, when in 1000Base-X mode, to ethtool ++ * advertisement settings. ++ */ ++static inline u32 mii_adv_to_ethtool_adv_x(u32 adv) ++{ ++ u32 result = 0; ++ ++ if (adv & ADVERTISE_1000XHALF) ++ result |= ADVERTISED_1000baseT_Half; ++ if (adv & ADVERTISE_1000XFULL) ++ result |= ADVERTISED_1000baseT_Full; ++ if (adv & ADVERTISE_1000XPAUSE) ++ result |= ADVERTISED_Pause; ++ if (adv & ADVERTISE_1000XPSE_ASYM) ++ result |= ADVERTISED_Asym_Pause; ++ ++ return result; ++} ++ ++/** ++ * mii_lpa_to_ethtool_lpa_x ++ * @adv: value of the MII_LPA register ++ * ++ * A small helper function that translates MII_LPA ++ * bits, when in 1000Base-X mode, to ethtool ++ * LP advertisement settings. ++ */ ++static inline u32 mii_lpa_to_ethtool_lpa_x(u32 lpa) ++{ ++ u32 result = 0; ++ ++ if (lpa & LPA_LPACK) ++ result |= ADVERTISED_Autoneg; ++ ++ return result | mii_adv_to_ethtool_adv_x(lpa); ++} ++ ++/** ++ * ethtool_rxfh_indir_default - get default value for RX flow hash indirection ++ * @index: Index in RX flow hash indirection table ++ * @n_rx_rings: Number of RX rings to use ++ * ++ * This function provides the default policy for RX flow hash indirection. ++ */ ++static inline u32 ethtool_rxfh_indir_default(u32 index, u32 n_rx_rings) ++{ ++ return index % n_rx_rings; ++} ++ ++#define ETHTOOL_FWVERS_LEN 32 ++ ++#if !((LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,9) && LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0)) || (LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,23) && LINUX_VERSION_CODE < KERNEL_VERSION(3,1,0))) ++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,37)) ++/* mask qdisc_cb_private_validate as RHEL6 backports this */ ++#define qdisc_cb_private_validate(a,b) compat_qdisc_cb_private_validate(a,b) ++static inline void qdisc_cb_private_validate(const struct sk_buff *skb, int sz) ++{ ++ BUILD_BUG_ON(sizeof(skb->cb) < sizeof(struct qdisc_skb_cb) + sz); ++} ++#else ++/* mask qdisc_cb_private_validate as RHEL6 backports this */ ++#define qdisc_cb_private_validate(a,b) compat_qdisc_cb_private_validate(a,b) ++static inline void qdisc_cb_private_validate(const struct sk_buff *skb, int sz) ++{ ++ /* XXX ? */ ++} ++#endif ++#endif ++ ++#define __pskb_copy LINUX_BACKPORT(__pskb_copy) ++extern struct sk_buff *__pskb_copy(struct sk_buff *skb, ++ int headroom, gfp_t gfp_mask); ++ ++static inline void skb_complete_wifi_ack(struct sk_buff *skb, bool acked) ++{ ++ WARN_ON(1); ++} ++#define NL80211_FEATURE_SK_TX_STATUS 0 ++ ++typedef u32 netdev_features_t; ++ ++/* source include/linux/device.h */ ++/** ++ * module_driver() - Helper macro for drivers that don't do anything ++ * special in module init/exit. This eliminates a lot of boilerplate. ++ * Each module may only use this macro once, and calling it replaces ++ * module_init() and module_exit(). ++ * ++ * Use this macro to construct bus specific macros for registering ++ * drivers, and do not use it on its own. ++ */ ++#define module_driver(__driver, __register, __unregister) \ ++static int __init __driver##_init(void) \ ++{ \ ++ return __register(&(__driver)); \ ++} \ ++module_init(__driver##_init); \ ++static void __exit __driver##_exit(void) \ ++{ \ ++ __unregister(&(__driver)); \ ++} \ ++module_exit(__driver##_exit); ++ ++/* source include/linux/usb.h */ ++/** ++ * module_usb_driver() - Helper macro for registering a USB driver ++ * @__usb_driver: usb_driver struct ++ * ++ * Helper macro for USB drivers which do not do anything special in module ++ * init/exit. This eliminates a lot of boilerplate. Each module may only ++ * use this macro once, and calling it replaces module_init() and module_exit() ++ */ ++#define module_usb_driver(__usb_driver) \ ++ module_driver(__usb_driver, usb_register, \ ++ usb_deregister) ++ ++ ++/* ++ * PCI_EXP_TYPE_RC_EC was added via 1b6b8ce2 on v2.6.30-rc4~20 : ++ * ++ * mcgrof@frijol ~/linux-next (git::master)$ git describe --contains 1b6b8ce2 ++ * v2.6.30-rc4~20^2 ++ * ++ * but the fix for its definition was merged on v3.3-rc1~101^2~67 ++ * ++ * mcgrof@frijol ~/linux-next (git::master)$ git describe --contains 1830ea91 ++ * v3.3-rc1~101^2~67 ++ * ++ * while we can assume it got merged and backported on v3.2.28 (which it did ++ * see c1c3cd9) we cannot assume every kernel has it fixed so lets just undef ++ * it here and redefine it. ++ */ ++#undef PCI_EXP_TYPE_RC_EC ++#define PCI_EXP_TYPE_RC_EC 0xa /* Root Complex Event Collector */ ++ ++#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0)) */ ++ ++#endif /* LINUX_3_3_COMPAT_H */ diff --cc compat/include/linux/compat-3.4.h index 000000000000,000000000000..3866330b5669 new file mode 100644 --- /dev/null +++ b/compat/include/linux/compat-3.4.h @@@ -1,0 -1,0 +1,149 @@@ ++#ifndef LINUX_3_4_COMPAT_H ++#define LINUX_3_4_COMPAT_H ++ ++#include ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0)) ++ ++/* ++ * defined here to allow things to compile but technically ++ * using this for memory regions will yield in a no-op on newer ++ * kernels but on older kernels (v3.3 and older) this bit was used ++ * for VM_ALWAYSDUMP. The goal was to remove this bit moving forward ++ * and since we can't skip the core dump on old kernels we just make ++ * this bit name now a no-op. ++ * ++ * For details see commits: 909af7 accb61fe cdaaa7003 ++ */ ++#define VM_NODUMP 0x0 ++ ++/* This backports: ++ * ++ * commit 63b2001169e75cd71e917ec953fdab572e3f944a ++ * Author: Thomas Gleixner ++ * Date: Thu Dec 1 00:04:00 2011 +0100 ++ ++ * sched/wait: Add __wake_up_all_locked() API ++ */ ++#include ++extern void compat_wake_up_locked(wait_queue_head_t *q, unsigned int mode, int nr); ++#define wake_up_all_locked(x) compat_wake_up_locked((x), TASK_NORMAL, 0) ++ ++/* This backports: ++ * ++ * commit a8203725dfded5c1f79dca3368a4a273e24b59bb ++ * Author: Xi Wang ++ * Date: Mon Mar 5 15:14:41 2012 -0800 ++ * ++ * slab: introduce kmalloc_array() ++ */ ++ ++/* SIZE_MAX is backported in compat-3.5.h so include it */ ++#include ++#define kmalloc_array LINUX_BACKPORT(kmalloc_array) ++static inline void *kmalloc_array(size_t n, size_t size, gfp_t flags) ++{ ++ if (size != 0 && n > SIZE_MAX / size) ++ return NULL; ++ return __kmalloc(n * size, flags); ++} ++ ++#include ++#include ++ ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34)) ++#define i2c_bit_algo LINUX_BACKPORT(i2c_bit_algo) ++extern const struct i2c_algorithm i2c_bit_algo; ++#endif ++ ++#define simple_open LINUX_BACKPORT(simple_open) ++extern int simple_open(struct inode *inode, struct file *file); ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)) ++#define skb_add_rx_frag(skb, i, page, off, size, truesize) \ ++ v2_6_28_skb_add_rx_frag(skb, i, page, off, size) ++#else ++#define skb_add_rx_frag(skb, i, page, off, size, truesize) \ ++ skb_add_rx_frag(skb, i, page, off, size) ++#endif ++ ++#ifdef CONFIG_X86_X32_ABI ++#define COMPAT_USE_64BIT_TIME \ ++ (!!(task_pt_regs(current)->orig_ax & __X32_SYSCALL_BIT)) ++#else ++#define COMPAT_USE_64BIT_TIME 0 ++#endif ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,12)) ++#define eth_hw_addr_random LINUX_BACKPORT(eth_hw_addr_random) ++static inline void eth_hw_addr_random(struct net_device *dev) ++{ ++#error eth_hw_addr_random() needs to be implemented for < 2.6.12 ++} ++#else /* kernels >= 2.6.12 */ ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,31)) ++#define eth_hw_addr_random LINUX_BACKPORT(eth_hw_addr_random) ++static inline void eth_hw_addr_random(struct net_device *dev) ++{ ++ get_random_bytes(dev->dev_addr, ETH_ALEN); ++ dev->dev_addr[0] &= 0xfe; /* clear multicast bit */ ++ dev->dev_addr[0] |= 0x02; /* set local assignment bit (IEEE802) */ ++} ++#else /* kernels >= 2.6.31 */ ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36)) ++/* So this is 2.6.31..2.6.35 */ ++ ++/* Just have the flags present, they won't really mean anything though */ ++#define NET_ADDR_PERM 0 /* address is permanent (default) */ ++#define NET_ADDR_RANDOM 1 /* address is generated randomly */ ++#define NET_ADDR_STOLEN 2 /* address is stolen from other device */ ++ ++#define eth_hw_addr_random LINUX_BACKPORT(eth_hw_addr_random) ++static inline void eth_hw_addr_random(struct net_device *dev) ++{ ++ random_ether_addr(dev->dev_addr); ++} ++ ++#else /* 2.6.36 and on */ ++#define eth_hw_addr_random LINUX_BACKPORT(eth_hw_addr_random) ++static inline void eth_hw_addr_random(struct net_device *dev) ++{ ++ dev_hw_addr_random(dev, dev->dev_addr); ++} ++#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,31)) */ ++ ++#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,31)) */ ++#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,12)) */ ++ ++/* source include/linux/pci.h */ ++/** ++ * module_pci_driver() - Helper macro for registering a PCI driver ++ * @__pci_driver: pci_driver struct ++ * ++ * Helper macro for PCI drivers which do not do anything special in module ++ * init/exit. This eliminates a lot of boilerplate. Each module may only ++ * use this macro once, and calling it replaces module_init() and module_exit() ++ */ ++#define module_pci_driver(__pci_driver) \ ++ module_driver(__pci_driver, pci_register_driver, \ ++ pci_unregister_driver) ++ ++/* ++ * Getting something that works in C and CPP for an arg that may or may ++ * not be defined is tricky. Here, if we have "#define CONFIG_BOOGER 1" ++ * we match on the placeholder define, insert the "0," for arg1 and generate ++ * the triplet (0, 1, 0). Then the last step cherry picks the 2nd arg (a one). ++ * When CONFIG_BOOGER is not defined, we generate a (... 1, 0) pair, and when ++ * the last step cherry picks the 2nd arg, we get a zero. ++ */ ++#define __ARG_PLACEHOLDER_1 0, ++#define config_enabled(cfg) _config_enabled(cfg) ++#define _config_enabled(value) __config_enabled(__ARG_PLACEHOLDER_##value) ++#define __config_enabled(arg1_or_junk) ___config_enabled(arg1_or_junk 1, 0) ++#define ___config_enabled(__ignored, val, ...) val ++ ++#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0)) */ ++ ++#endif /* LINUX_5_4_COMPAT_H */ diff --cc compat/include/linux/compat-3.5.h index 000000000000,000000000000..57b06b04f975 new file mode 100644 --- /dev/null +++ b/compat/include/linux/compat-3.5.h @@@ -1,0 -1,0 +1,302 @@@ ++#ifndef LINUX_3_5_COMPAT_H ++#define LINUX_3_5_COMPAT_H ++ ++#include ++#include ++#include ++#include ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) ++ ++#include ++ ++/* ++ * This backports: ++ * commit 569a8fc38367dfafd87454f27ac646c8e6b54bca ++ * Author: David S. Miller ++ * Date: Thu Mar 29 23:18:53 2012 -0400 ++ * ++ * netlink: Add nla_put_be{16,32,64}() helpers. ++ */ ++ ++static inline int nla_put_be16(struct sk_buff *skb, int attrtype, __be16 value) ++{ ++ return nla_put(skb, attrtype, sizeof(__be16), &value); ++} ++ ++static inline int nla_put_be32(struct sk_buff *skb, int attrtype, __be32 value) ++{ ++ return nla_put(skb, attrtype, sizeof(__be32), &value); ++} ++ ++static inline int nla_put_be64(struct sk_buff *skb, int attrtype, __be64 value) ++{ ++ return nla_put(skb, attrtype, sizeof(__be64), &value); ++} ++ ++/* ++ * This backports: ++ * ++ * commit f56f821feb7b36223f309e0ec05986bb137ce418 ++ * Author: Daniel Vetter ++ * Date: Sun Mar 25 19:47:41 2012 +0200 ++ * ++ * mm: extend prefault helpers to fault in more than PAGE_SIZE ++ * ++ * The new functions are used by drm/i915 driver. ++ * ++ */ ++ ++static inline int fault_in_multipages_writeable(char __user *uaddr, int size) ++{ ++ int ret = 0; ++ char __user *end = uaddr + size - 1; ++ ++ if (unlikely(size == 0)) ++ return ret; ++ ++ /* ++ * Writing zeroes into userspace here is OK, because we know that if ++ * the zero gets there, we'll be overwriting it. ++ */ ++ while (uaddr <= end) { ++ ret = __put_user(0, uaddr); ++ if (ret != 0) ++ return ret; ++ uaddr += PAGE_SIZE; ++ } ++ ++ /* Check whether the range spilled into the next page. */ ++ if (((unsigned long)uaddr & PAGE_MASK) == ++ ((unsigned long)end & PAGE_MASK)) ++ ret = __put_user(0, end); ++ ++ return ret; ++} ++ ++static inline int fault_in_multipages_readable(const char __user *uaddr, ++ int size) ++{ ++ volatile char c; ++ int ret = 0; ++ const char __user *end = uaddr + size - 1; ++ ++ if (unlikely(size == 0)) ++ return ret; ++ ++ while (uaddr <= end) { ++ ret = __get_user(c, uaddr); ++ if (ret != 0) ++ return ret; ++ uaddr += PAGE_SIZE; ++ } ++ ++ /* Check whether the range spilled into the next page. */ ++ if (((unsigned long)uaddr & PAGE_MASK) == ++ ((unsigned long)end & PAGE_MASK)) { ++ ret = __get_user(c, end); ++ (void)c; ++ } ++ ++ return ret; ++} ++ ++/* switcheroo is available on >= 2.6.34 */ ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34)) ++#include ++/* ++ * This backports: ++ * ++ * From 26ec685ff9d9c16525d8ec4c97e52fcdb187b302 Mon Sep 17 00:00:00 2001 ++ * From: Takashi Iwai ++ * Date: Fri, 11 May 2012 07:51:17 +0200 ++ * Subject: [PATCH] vga_switcheroo: Introduce struct vga_switcheroo_client_ops ++ * ++ */ ++ ++struct vga_switcheroo_client_ops { ++ void (*set_gpu_state)(struct pci_dev *dev, enum vga_switcheroo_state); ++ void (*reprobe)(struct pci_dev *dev); ++ bool (*can_switch)(struct pci_dev *dev); ++}; ++ ++/* Wrap around the old code and redefine vga_switcheroo_register_client() ++ * for older kernels < 3.5.0. ++ */ ++static inline int compat_vga_switcheroo_register_client(struct pci_dev *dev, ++ const struct vga_switcheroo_client_ops *ops) { ++ ++ return vga_switcheroo_register_client(dev, ++ ops->set_gpu_state, ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) ++ ops->reprobe, ++#endif ++ ops->can_switch); ++} ++ ++#define vga_switcheroo_register_client(_dev, _ops) \ ++ compat_vga_switcheroo_register_client(_dev, _ops) ++ ++#endif ++ ++/* This backports ++ * ++ * commit 14674e70119ea01549ce593d8901a797f8a90f74 ++ * Author: Mark Brown ++ * Date: Wed May 30 10:55:34 2012 +0200 ++ * ++ * i2c: Split I2C_M_NOSTART support out of I2C_FUNC_PROTOCOL_MANGLING ++ */ ++ ++#define I2C_FUNC_NOSTART 0x00000010 /* I2C_M_NOSTART */ ++ ++/* ++ * This backports: ++ * ++ * From a3860c1c5dd1137db23d7786d284939c5761d517 Mon Sep 17 00:00:00 2001 ++ * From: Xi Wang ++ * Date: Thu, 31 May 2012 16:26:04 -0700 ++ * Subject: [PATCH] introduce SIZE_MAX ++ */ ++ ++#define SIZE_MAX (~(size_t)0) ++ ++ ++#include ++ ++/* ++ * This backports: ++ * ++ * From 76e3cc126bb223013a6b9a0e2a51238d1ef2e409 Mon Sep 17 00:00:00 2001 ++ * From: Eric Dumazet ++ * Date: Thu, 10 May 2012 07:51:25 +0000 ++ * Subject: [PATCH] codel: Controlled Delay AQM ++ */ ++ ++#ifndef TCA_CODEL_MAX ++/* CODEL */ ++ ++#define COMPAT_CODEL_BACKPORT ++ ++enum { ++ TCA_CODEL_UNSPEC, ++ TCA_CODEL_TARGET, ++ TCA_CODEL_LIMIT, ++ TCA_CODEL_INTERVAL, ++ TCA_CODEL_ECN, ++ __TCA_CODEL_MAX ++}; ++ ++#define TCA_CODEL_MAX (__TCA_CODEL_MAX - 1) ++ ++struct tc_codel_xstats { ++ __u32 maxpacket; /* largest packet we've seen so far */ ++ __u32 count; /* how many drops we've done since the last time we ++ * entered dropping state ++ */ ++ __u32 lastcount; /* count at entry to dropping state */ ++ __u32 ldelay; /* in-queue delay seen by most recently dequeued packet */ ++ __s32 drop_next; /* time to drop next packet */ ++ __u32 drop_overlimit; /* number of time max qdisc packet limit was hit */ ++ __u32 ecn_mark; /* number of packets we ECN marked instead of dropped */ ++ __u32 dropping; /* are we in dropping state ? */ ++}; ++ ++/* This backports: ++ * ++ * commit 4b549a2ef4bef9965d97cbd992ba67930cd3e0fe ++ * Author: Eric Dumazet ++ * Date: Fri May 11 09:30:50 2012 +0000 ++ * fq_codel: Fair Queue Codel AQM ++ */ ++ ++/* FQ_CODEL */ ++ ++enum { ++ TCA_FQ_CODEL_UNSPEC, ++ TCA_FQ_CODEL_TARGET, ++ TCA_FQ_CODEL_LIMIT, ++ TCA_FQ_CODEL_INTERVAL, ++ TCA_FQ_CODEL_ECN, ++ TCA_FQ_CODEL_FLOWS, ++ TCA_FQ_CODEL_QUANTUM, ++ __TCA_FQ_CODEL_MAX ++}; ++ ++#define TCA_FQ_CODEL_MAX (__TCA_FQ_CODEL_MAX - 1) ++ ++enum { ++ TCA_FQ_CODEL_XSTATS_QDISC, ++ TCA_FQ_CODEL_XSTATS_CLASS, ++}; ++ ++struct tc_fq_codel_qd_stats { ++ __u32 maxpacket; /* largest packet we've seen so far */ ++ __u32 drop_overlimit; /* number of time max qdisc ++ * packet limit was hit ++ */ ++ __u32 ecn_mark; /* number of packets we ECN marked ++ * instead of being dropped ++ */ ++ __u32 new_flow_count; /* number of time packets ++ * created a 'new flow' ++ */ ++ __u32 new_flows_len; /* count of flows in new list */ ++ __u32 old_flows_len; /* count of flows in old list */ ++}; ++ ++struct tc_fq_codel_cl_stats { ++ __s32 deficit; ++ __u32 ldelay; /* in-queue delay seen by most recently ++ * dequeued packet ++ */ ++ __u32 count; ++ __u32 lastcount; ++ __u32 dropping; ++ __s32 drop_next; ++}; ++ ++struct tc_fq_codel_xstats { ++ __u32 type; ++ union { ++ struct tc_fq_codel_qd_stats qdisc_stats; ++ struct tc_fq_codel_cl_stats class_stats; ++ }; ++}; ++#endif /* TCA_CODEL_MAX */ ++ ++/* Backport ether_addr_equal */ ++static inline bool ether_addr_equal(const u8 *addr1, const u8 *addr2) ++{ ++ return !compare_ether_addr(addr1, addr2); ++} ++ ++#define net_ratelimited_function(function, ...) \ ++do { \ ++ if (net_ratelimit()) \ ++ function(__VA_ARGS__); \ ++} while (0) ++ ++#define net_emerg_ratelimited(fmt, ...) \ ++ net_ratelimited_function(pr_emerg, fmt, ##__VA_ARGS__) ++#define net_alert_ratelimited(fmt, ...) \ ++ net_ratelimited_function(pr_alert, fmt, ##__VA_ARGS__) ++#define net_crit_ratelimited(fmt, ...) \ ++ net_ratelimited_function(pr_crit, fmt, ##__VA_ARGS__) ++#define net_err_ratelimited(fmt, ...) \ ++ net_ratelimited_function(pr_err, fmt, ##__VA_ARGS__) ++#define net_notice_ratelimited(fmt, ...) \ ++ net_ratelimited_function(pr_notice, fmt, ##__VA_ARGS__) ++#define net_warn_ratelimited(fmt, ...) \ ++ net_ratelimited_function(pr_warn, fmt, ##__VA_ARGS__) ++#define net_info_ratelimited(fmt, ...) \ ++ net_ratelimited_function(pr_info, fmt, ##__VA_ARGS__) ++#define net_dbg_ratelimited(fmt, ...) \ ++ net_ratelimited_function(pr_debug, fmt, ##__VA_ARGS__) ++ ++#define ktime_get_monotonic_offset LINUX_BACKPORT(ktime_get_monotonic_offset) ++extern ktime_t ktime_get_monotonic_offset(void); ++ ++#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)) */ ++ ++#endif /* LINUX_3_5_COMPAT_H */ diff --cc compat/include/linux/compat-3.6.h index 000000000000,000000000000..d9c964ed3f9a new file mode 100644 --- /dev/null +++ b/compat/include/linux/compat-3.6.h @@@ -1,0 -1,0 +1,109 @@@ ++#ifndef LINUX_3_6_COMPAT_H ++#define LINUX_3_6_COMPAT_H ++ ++#include ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0)) ++ ++#include ++ ++/* backports efc42bc9 */ ++#define sg_alloc_table_from_pages LINUX_BACKPORT(sg_alloc_table_from_pages) ++int sg_alloc_table_from_pages(struct sg_table *sgt, ++ struct page **pages, unsigned int n_pages, ++ unsigned long offset, unsigned long size, ++ gfp_t gfp_mask); ++ ++/** ++ * Backports ++ * ++ * commit d81a5d1956731c453b85c141458d4ff5d6cc5366 ++ * Author: Gustavo Padovan ++ * Date: Tue Jul 10 19:10:06 2012 -0300 ++ * ++ * USB: add USB_VENDOR_AND_INTERFACE_INFO() macro ++ */ ++#include ++#define USB_VENDOR_AND_INTERFACE_INFO(vend, cl, sc, pr) \ ++ .match_flags = USB_DEVICE_ID_MATCH_INT_INFO \ ++ | USB_DEVICE_ID_MATCH_VENDOR, \ ++ .idVendor = (vend), \ ++ .bInterfaceClass = (cl), \ ++ .bInterfaceSubClass = (sc), \ ++ .bInterfaceProtocol = (pr) ++ ++/** ++ * Backports ++ * ++ * commit cdcac9cd7741af2c2b9255cbf060f772596907bb ++ * Author: Dave Airlie ++ * Date: Wed Jun 27 08:35:52 2012 +0100 ++ * ++ * pci_regs: define LNKSTA2 pcie cap + bits. ++ * ++ * We need these for detecting the max link speed for drm drivers. ++ * ++ * Acked-by: Bjorn Helgaas ++ * Signed-off-by: Dave Airlie ++ */ ++ ++#define PCI_EXP_LNKCAP2 44 /* Link Capability 2 */ ++#define PCI_EXP_LNKCAP2_SLS_2_5GB 0x01 /* Current Link Speed 2.5GT/s */ ++#define PCI_EXP_LNKCAP2_SLS_5_0GB 0x02 /* Current Link Speed 5.0GT/s */ ++#define PCI_EXP_LNKCAP2_SLS_8_0GB 0x04 /* Current Link Speed 8.0GT/s */ ++#define PCI_EXP_LNKCAP2_CROSSLINK 0x100 /* Crosslink supported */ ++ ++#include ++#include ++ ++/** ++ * eth_broadcast_addr - Assign broadcast address ++ * @addr: Pointer to a six-byte array containing the Ethernet address ++ * ++ * Assign the broadcast address to the given address array. ++ */ ++static inline void eth_broadcast_addr(u8 *addr) ++{ ++ memset(addr, 0xff, ETH_ALEN); ++} ++ ++/** ++ * eth_random_addr - Generate software assigned random Ethernet address ++ * @addr: Pointer to a six-byte array containing the Ethernet address ++ * ++ * Generate a random Ethernet address (MAC) that is not multicast ++ * and has the local assigned bit set. ++ */ ++static inline void eth_random_addr(u8 *addr) ++{ ++ get_random_bytes(addr, ETH_ALEN); ++ addr[0] &= 0xfe; /* clear multicast bit */ ++ addr[0] |= 0x02; /* set local assignment bit (IEEE802) */ ++} ++ ++#define GENLMSG_DEFAULT_SIZE (NLMSG_DEFAULT_SIZE - GENL_HDRLEN) ++ ++/* ++ * Backports ++ * ++ * commit 959d62fa865d2e616b61a509e1cc5b88741f065e ++ * Author: Shuah Khan ++ * Date: Thu Jun 14 04:34:30 2012 +0800 ++ * ++ * leds: Rename led_brightness_set() to led_set_brightness() ++ * ++ * Rename leds external interface led_brightness_set() to led_set_brightness(). ++ * This is the second phase of the change to reduce confusion between the ++ * leds internal and external interfaces that set brightness. With this change, ++ * now the external interface is led_set_brightness(). The first phase renamed ++ * the internal interface led_set_brightness() to __led_set_brightness(). ++ * There are no changes to the interface implementations. ++ * ++ * Signed-off-by: Shuah Khan ++ * Signed-off-by: Bryan Wu ++ */ ++#define led_set_brightness(_dev, _switch) led_brightness_set(_dev, _switch) ++ ++#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0)) */ ++ ++#endif /* LINUX_3_6_COMPAT_H */ diff --cc compat/include/linux/compat-3.7.h index 000000000000,000000000000..96662e373ebd new file mode 100644 --- /dev/null +++ b/compat/include/linux/compat-3.7.h @@@ -1,0 -1,0 +1,216 @@@ ++#ifndef LINUX_3_7_COMPAT_H ++#define LINUX_3_7_COMPAT_H ++ ++#include ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,7,0)) ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define VM_DONTDUMP VM_NODUMP ++ ++#ifdef CONFIG_USER_NS ++ ++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38)) ++static inline struct user_namespace *seq_user_ns(struct seq_file *seq) ++{ ++ struct file *f = container_of((void *) seq, struct file, private_data); ++ ++ return f->f_cred->user_ns; ++} ++#else ++static inline struct user_namespace *seq_user_ns(struct seq_file *seq) ++{ ++ return current_user_ns(); ++} ++#endif /* (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38)) */ ++ ++#else ++static inline struct user_namespace *seq_user_ns(struct seq_file *seq) ++{ ++ extern struct user_namespace init_user_ns; ++ return &init_user_ns; ++} ++#endif /* CONFIG_USER_NS */ ++ ++#define netlink_notify_portid(__notify) (__notify->pid) ++#define genl_info_snd_portid(__genl_info) (__genl_info->snd_pid) ++#define NETLINK_CB_PORTID(__skb) NETLINK_CB(cb->skb).pid ++ ++#define mod_delayed_work LINUX_BACKPORT(mod_delayed_work) ++bool mod_delayed_work(struct workqueue_struct *wq, struct delayed_work *dwork, ++ unsigned long delay); ++ ++/* Backports tty_lock: Localise the lock */ ++#define tty_lock(__tty) tty_lock() ++#define tty_unlock(__tty) tty_unlock() ++ ++#define tty_port_register_device(port, driver, index, device) \ ++ tty_register_device(driver, index, device) ++ ++#define pcie_capability_read_word LINUX_BACKPORT(pcie_capability_read_word) ++int pcie_capability_read_word(struct pci_dev *dev, int pos, u16 *val); ++#define pcie_capability_read_dword LINUX_BACKPORT(pcie_capability_read_dword) ++int pcie_capability_read_dword(struct pci_dev *dev, int pos, u32 *val); ++#define pcie_capability_write_word LINUX_BACKPORT(pcie_capability_write_word) ++int pcie_capability_write_word(struct pci_dev *dev, int pos, u16 val); ++#define pcie_capability_write_dword LINUX_BACKPORT(pcie_capability_write_dword) ++int pcie_capability_write_dword(struct pci_dev *dev, int pos, u32 val); ++#define pcie_capability_clear_and_set_word LINUX_BACKPORT(pcie_capability_clear_and_set_word) ++int pcie_capability_clear_and_set_word(struct pci_dev *dev, int pos, ++ u16 clear, u16 set); ++#define pcie_capability_clear_and_set_dword LINUX_BACKPORT(pcie_capability_clear_and_set_dword) ++int pcie_capability_clear_and_set_dword(struct pci_dev *dev, int pos, ++ u32 clear, u32 set); ++ ++static inline int pcie_capability_set_word(struct pci_dev *dev, int pos, ++ u16 set) ++{ ++ return pcie_capability_clear_and_set_word(dev, pos, 0, set); ++} ++ ++static inline int pcie_capability_set_dword(struct pci_dev *dev, int pos, ++ u32 set) ++{ ++ return pcie_capability_clear_and_set_dword(dev, pos, 0, set); ++} ++ ++static inline int pcie_capability_clear_word(struct pci_dev *dev, int pos, ++ u16 clear) ++{ ++ return pcie_capability_clear_and_set_word(dev, pos, clear, 0); ++} ++ ++static inline int pcie_capability_clear_dword(struct pci_dev *dev, int pos, ++ u32 clear) ++{ ++ return pcie_capability_clear_and_set_dword(dev, pos, clear, 0); ++} ++ ++#define PCI_EXP_LNKSTA2 50 /* Link Status 2 */ ++ ++/* This backports: ++ * ++ * commit 6d57e9078e880a3dd232d579f42ac437a8f1ef7b ++ * Author: Duan Jiong ++ * Date: Sat Sep 8 16:32:28 2012 +0000 ++ * ++ * etherdevice: introduce help function eth_zero_addr() ++ */ ++/** ++ * eth_zero_addr - Assign zero address ++ * @addr: Pointer to a six-byte array containing the Ethernet address ++ * ++ * Assign the zero address to the given address array. ++ */ ++static inline void eth_zero_addr(u8 *addr) ++{ ++ memset(addr, 0x00, ETH_ALEN); ++} ++ ++/** ++ * nla_put_s8 - Add a s8 netlink attribute to a socket buffer ++ * @skb: socket buffer to add attribute to ++ * @attrtype: attribute type ++ * @value: numeric value ++ */ ++static inline int nla_put_s8(struct sk_buff *skb, int attrtype, s8 value) ++{ ++ return nla_put(skb, attrtype, sizeof(s8), &value); ++} ++ ++/** ++ * nla_put_s16 - Add a s16 netlink attribute to a socket buffer ++ * @skb: socket buffer to add attribute to ++ * @attrtype: attribute type ++ * @value: numeric value ++ */ ++static inline int nla_put_s16(struct sk_buff *skb, int attrtype, s16 value) ++{ ++ return nla_put(skb, attrtype, sizeof(s16), &value); ++} ++ ++/** ++ * nla_put_s32 - Add a s32 netlink attribute to a socket buffer ++ * @skb: socket buffer to add attribute to ++ * @attrtype: attribute type ++ * @value: numeric value ++ */ ++static inline int nla_put_s32(struct sk_buff *skb, int attrtype, s32 value) ++{ ++ return nla_put(skb, attrtype, sizeof(s32), &value); ++} ++ ++/** ++ * nla_put_s64 - Add a s64 netlink attribute to a socket buffer ++ * @skb: socket buffer to add attribute to ++ * @attrtype: attribute type ++ * @value: numeric value ++ */ ++static inline int nla_put_s64(struct sk_buff *skb, int attrtype, s64 value) ++{ ++ return nla_put(skb, attrtype, sizeof(s64), &value); ++} ++ ++/** ++ * nla_get_s32 - return payload of s32 attribute ++ * @nla: s32 netlink attribute ++ */ ++static inline s32 nla_get_s32(const struct nlattr *nla) ++{ ++ return *(s32 *) nla_data(nla); ++} ++ ++/** ++ * nla_get_s16 - return payload of s16 attribute ++ * @nla: s16 netlink attribute ++ */ ++static inline s16 nla_get_s16(const struct nlattr *nla) ++{ ++ return *(s16 *) nla_data(nla); ++} ++ ++/** ++ * nla_get_s8 - return payload of s8 attribute ++ * @nla: s8 netlink attribute ++ */ ++static inline s8 nla_get_s8(const struct nlattr *nla) ++{ ++ return *(s8 *) nla_data(nla); ++} ++ ++/** ++ * nla_get_s64 - return payload of s64 attribute ++ * @nla: s64 netlink attribute ++ */ ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)) ++static inline s64 nla_get_s64(const struct nlattr *nla) ++#else ++static inline s64 nla_get_s64(struct nlattr *nla) ++#endif ++{ ++ s64 tmp; ++ ++ nla_memcpy(&tmp, nla, sizeof(tmp)); ++ ++ return tmp; ++} ++ ++#define PLATFORM_DEVID_NONE (-1) ++#define PLATFORM_DEVID_AUTO (-1) ++ ++#else /* (LINUX_VERSION_CODE > KERNEL_VERSION(3,7,0)) */ ++#define netlink_notify_portid(__notify) (__notify->portid) ++#define genl_info_snd_portid(__genl_info) (__genl_info->snd_portid) ++#define NETLINK_CB_PORTID(__skb) NETLINK_CB(cb->skb).portid ++#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(3,7,0)) */ ++ ++#endif /* LINUX_3_7_COMPAT_H */ diff --cc compat/include/linux/compat-3.8.h index 000000000000,000000000000..55fdc165422f new file mode 100644 --- /dev/null +++ b/compat/include/linux/compat-3.8.h @@@ -1,0 -1,0 +1,131 @@@ ++#ifndef LINUX_3_8_COMPAT_H ++#define LINUX_3_8_COMPAT_H ++ ++#include ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)) ++ ++#include ++#include ++#include ++#include ++ ++/* backports 496f2f9 */ ++#define prandom_seed(_seed) srandom32(_seed) ++#define prandom_u32() random32() ++#define prandom_u32_state(_state) prandom32(_state) ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,7,8)) ++#define netdev_set_default_ethtool_ops LINUX_BACKPORT(netdev_set_default_ethtool_ops) ++extern void netdev_set_default_ethtool_ops(struct net_device *dev, ++ const struct ethtool_ops *ops); ++#endif ++ ++#define HID_BUS_ANY 0xffff ++#define HID_GROUP_ANY 0x0000 ++ ++#define PCI_EXP_LNKCTL_ASPM_L0S 0x01 /* L0s Enable */ ++#define PCI_EXP_LNKCTL_ASPM_L1 0x02 /* L1 Enable */ ++ ++#define hid_ignore LINUX_BACKPORT(hid_ignore) ++extern bool hid_ignore(struct hid_device *); ++ ++/* This backports: ++ * ++ * commit 4b20db3de8dab005b07c74161cb041db8c5ff3a7 ++ * Author: Thomas Hellstrom ++ * Date: Tue Nov 6 11:31:49 2012 +0000 ++ * ++ * kref: Implement kref_get_unless_zero v3 ++ */ ++/** ++ * kref_get_unless_zero - Increment refcount for object unless it is zero. ++ * @kref: object. ++ * ++ * Return non-zero if the increment succeeded. Otherwise return 0. ++ * ++ * This function is intended to simplify locking around refcounting for ++ * objects that can be looked up from a lookup structure, and which are ++ * removed from that lookup structure in the object destructor. ++ * Operations on such objects require at least a read lock around ++ * lookup + kref_get, and a write lock around kref_put + remove from lookup ++ * structure. Furthermore, RCU implementations become extremely tricky. ++ * With a lookup followed by a kref_get_unless_zero *with return value check* ++ * locking in the kref_put path can be deferred to the actual removal from ++ * the lookup structure and RCU lookups become trivial. ++ */ ++static inline int __must_check kref_get_unless_zero(struct kref *kref) ++{ ++ return atomic_add_unless(&kref->refcount, 1, 0); ++} ++ ++/* This backports: ++ * ++ * commit 83e68189745ad931c2afd45d8ee3303929233e7f ++ * Author: Matt Fleming ++ * Date: Wed Nov 14 09:42:35 2012 +0000 ++ * ++ * efi: Make 'efi_enabled' a function to query EFI facilities ++ * ++ */ ++/* check first if this was already backported */ ++#ifndef EFI_BOOT ++/* ++ * We play games with efi_enabled so that the compiler will, if ++ * possible, remove EFI-related code altogether. ++ */ ++#define EFI_BOOT 0 /* Were we booted from EFI? */ ++#define EFI_SYSTEM_TABLES 1 /* Can we use EFI system tables? */ ++#define EFI_CONFIG_TABLES 2 /* Can we use EFI config tables? */ ++#define EFI_RUNTIME_SERVICES 3 /* Can we use runtime services? */ ++#define EFI_MEMMAP 4 /* Can we use EFI memory map? */ ++#define EFI_64BIT 5 /* Is the firmware 64-bit? */ ++ ++#ifdef CONFIG_EFI ++# ifdef CONFIG_X86 ++static inline int compat_efi_enabled(int facility) ++{ ++ switch (facility) { ++ case EFI_BOOT: ++ return efi_enabled; ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)) ++ case EFI_64BIT: ++ return efi_64bit; ++#endif ++ default: ++ printk(KERN_ERR "can not translate efi_enabled() to old values completly\n"); ++ return efi_enabled; ++ } ++} ++# else ++static inline int compat_efi_enabled(int facility) ++{ ++ return 1; ++} ++# endif ++#else ++static inline int compat_efi_enabled(int facility) ++{ ++ return 0; ++} ++#endif ++#ifdef efi_enabled ++#undef efi_enabled ++#endif ++#define efi_enabled(facility) compat_efi_enabled(facility) ++#endif /* EFI_BOOT */ ++ ++/* This backports: ++ * ++ * commit 130f1b8f35f14d27c43da755f3c9226318c17f57 ++ * Author: Bjorn Helgaas ++ * Date: Wed Dec 26 10:39:23 2012 -0700 ++ * ++ * PCI: Add PCIe Link Capability link speed and width names ++ */ ++#define PCI_EXP_LNKCAP_SLS_2_5GB 0x1 /* LNKCAP2 SLS Vector bit 0 (2.5GT/s) */ ++#define PCI_EXP_LNKCAP_SLS_5_0GB 0x2 /* LNKCAP2 SLS Vector bit 1 (5.0GT/s) */ ++ ++#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0)) */ ++ ++#endif /* LINUX_3_8_COMPAT_H */ diff --cc compat/include/linux/compat-3.9.h index 000000000000,000000000000..240a328d7b6c new file mode 100644 --- /dev/null +++ b/compat/include/linux/compat-3.9.h @@@ -1,0 -1,0 +1,208 @@@ ++#ifndef LINUX_3_9_COMPAT_H ++#define LINUX_3_9_COMPAT_H ++ ++#include ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,9,0)) ++ ++#include ++#include ++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,25)) ++#include ++#endif ++#include ++#include ++#include ++#include ++#include ++ ++/* include this before changing hlist_for_each_* to use the old versions. */ ++#include ++ ++/* Lets expect distributions might backport this */ ++ ++#ifndef for_each_sg_page ++/* ++ * sg page iterator ++ * ++ * Iterates over sg entries page-by-page. On each successful iteration, ++ * @piter->page points to the current page, @piter->sg to the sg holding this ++ * page and @piter->sg_pgoffset to the page's page offset within the sg. The ++ * iteration will stop either when a maximum number of sg entries was reached ++ * or a terminating sg (sg_last(sg) == true) was reached. ++ */ ++struct sg_page_iter { ++ struct page *page; /* current page */ ++ struct scatterlist *sg; /* sg holding the page */ ++ unsigned int sg_pgoffset; /* page offset within the sg */ ++ ++ /* these are internal states, keep away */ ++ unsigned int __nents; /* remaining sg entries */ ++ int __pg_advance; /* nr pages to advance at the ++ * next step */ ++}; ++ ++#define __sg_page_iter_next LINUX_BACKPORT(__sg_page_iter_next) ++bool __sg_page_iter_next(struct sg_page_iter *piter); ++#define __sg_page_iter_start LINUX_BACKPORT(__sg_page_iter_start) ++void __sg_page_iter_start(struct sg_page_iter *piter, ++ struct scatterlist *sglist, unsigned int nents, ++ unsigned long pgoffset); ++ ++/** ++ * for_each_sg_page - iterate over the pages of the given sg list ++ * @sglist: sglist to iterate over ++ * @piter: page iterator to hold current page, sg, sg_pgoffset ++ * @nents: maximum number of sg entries to iterate over ++ * @pgoffset: starting page offset ++ */ ++#define for_each_sg_page(sglist, piter, nents, pgoffset) \ ++ for (__sg_page_iter_start((piter), (sglist), (nents), (pgoffset)); \ ++ __sg_page_iter_next(piter);) ++ ++#endif /* for_each_sg_page assumption */ ++ ++/* backports 7a555613 */ ++#if defined(CONFIG_DYNAMIC_DEBUG) ++#define dynamic_hex_dump(prefix_str, prefix_type, rowsize, \ ++ groupsize, buf, len, ascii) \ ++do { \ ++ DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, \ ++ __builtin_constant_p(prefix_str) ? prefix_str : "hexdump");\ ++ if (unlikely(descriptor.flags & _DPRINTK_FLAGS_PRINT)) \ ++ print_hex_dump(KERN_DEBUG, prefix_str, \ ++ prefix_type, rowsize, groupsize, \ ++ buf, len, ascii); \ ++} while (0) ++#define print_hex_dump_debug(prefix_str, prefix_type, rowsize, \ ++ groupsize, buf, len, ascii) \ ++ dynamic_hex_dump(prefix_str, prefix_type, rowsize, \ ++ groupsize, buf, len, ascii) ++#else ++#define print_hex_dump_debug(prefix_str, prefix_type, rowsize, \ ++ groupsize, buf, len, ascii) \ ++ print_hex_dump(KERN_DEBUG, prefix_str, prefix_type, rowsize, \ ++ groupsize, buf, len, ascii) ++#endif /* defined(CONFIG_DYNAMIC_DEBUG) */ ++ ++ ++/** ++ * backport of idr idr_alloc() usage ++ * ++ * This backports a patch series send by Tejun Heo: ++ * https://lkml.org/lkml/2013/2/2/159 ++ */ ++static inline void compat_idr_destroy(struct idr *idp) ++{ ++ idr_remove_all(idp); ++ idr_destroy(idp); ++} ++#define idr_destroy(idp) compat_idr_destroy(idp) ++ ++static inline int idr_alloc(struct idr *idr, void *ptr, int start, int end, ++ gfp_t gfp_mask) ++{ ++ int id, ret; ++ ++ do { ++ if (!idr_pre_get(idr, gfp_mask)) ++ return -ENOMEM; ++ ret = idr_get_new_above(idr, ptr, start, &id); ++ if (!ret && id > end) { ++ idr_remove(idr, id); ++ ret = -ENOSPC; ++ } ++ } while (ret == -EAGAIN); ++ ++ return ret ? ret : id; ++} ++ ++static inline void idr_preload(gfp_t gfp_mask) ++{ ++} ++ ++static inline void idr_preload_end(void) ++{ ++} ++ ++ ++/** ++ * backport: ++ * ++ * commit 0bbacca7c3911451cea923b0ad6389d58e3d9ce9 ++ * Author: Sasha Levin ++ * Date: Thu Feb 7 12:32:18 2013 +1100 ++ * ++ * hlist: drop the node parameter from iterators ++ */ ++ ++#define hlist_entry_safe(ptr, type, member) \ ++ (ptr) ? hlist_entry(ptr, type, member) : NULL ++ ++#undef hlist_for_each_entry ++/** ++ * hlist_for_each_entry - iterate over list of given type ++ * @pos: the type * to use as a loop cursor. ++ * @head: the head for your list. ++ * @member: the name of the hlist_node within the struct. ++ */ ++#define hlist_for_each_entry(pos, head, member) \ ++ for (pos = hlist_entry_safe((head)->first, typeof(*(pos)), member); \ ++ pos; \ ++ pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member)) ++ ++#undef hlist_for_each_entry_safe ++/** ++ * hlist_for_each_entry_safe - iterate over list of given type safe against removal of list entry ++ * @pos: the type * to use as a loop cursor. ++ * @n: another &struct hlist_node to use as temporary storage ++ * @head: the head for your list. ++ * @member: the name of the hlist_node within the struct. ++ */ ++#define hlist_for_each_entry_safe(pos, n, head, member) \ ++ for (pos = hlist_entry_safe((head)->first, typeof(*pos), member); \ ++ pos && ({ n = pos->member.next; 1; }); \ ++ pos = hlist_entry_safe(n, typeof(*pos), member)) ++ ++#undef hlist_for_each_entry_rcu ++/** ++ * hlist_for_each_entry_rcu - iterate over rcu list of given type ++ * @pos: the type * to use as a loop cursor. ++ * @head: the head for your list. ++ * @member: the name of the hlist_node within the struct. ++ * ++ * This list-traversal primitive may safely run concurrently with ++ * the _rcu list-mutation primitives such as hlist_add_head_rcu() ++ * as long as the traversal is guarded by rcu_read_lock(). ++ */ ++#define hlist_for_each_entry_rcu(pos, head, member) \ ++ for (pos = hlist_entry_safe (rcu_dereference_raw(hlist_first_rcu(head)),\ ++ typeof(*(pos)), member); \ ++ pos; \ ++ pos = hlist_entry_safe(rcu_dereference_raw(hlist_next_rcu( \ ++ &(pos)->member)), typeof(*(pos)), member)) ++ ++#undef sk_for_each ++#define sk_for_each(__sk, list) \ ++ hlist_for_each_entry(__sk, list, sk_node) ++ ++#define tty_flip_buffer_push(port) tty_flip_buffer_push((port)->tty) ++#define tty_insert_flip_string(port, chars, size) tty_insert_flip_string((port)->tty, chars, size) ++ ++/** ++ * backport of: ++ * ++ * commit 496ad9aa8ef448058e36ca7a787c61f2e63f0f54 ++ * Author: Al Viro ++ * Date: Wed Jan 23 17:07:38 2013 -0500 ++ * ++ * new helper: file_inode(file) ++ */ ++static inline struct inode *file_inode(struct file *f) ++{ ++ return f->f_path.dentry->d_inode; ++} ++ ++#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(3,9,0)) */ ++ ++#endif /* LINUX_3_9_COMPAT_H */ diff --cc compat/include/linux/cordic.h index 000000000000,000000000000..7f27b007e650 new file mode 100644 --- /dev/null +++ b/compat/include/linux/cordic.h @@@ -1,0 -1,0 +1,60 @@@ ++#ifndef _BACKPORT_LINUX_CORDIC_H ++#define _BACKPORT_LINUX_CORDIC_H 1 ++ ++#include ++ ++#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,1,0)) ++#include_next ++#else ++ ++/* ++ * Copyright (c) 2011 Broadcom Corporation ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ */ ++#ifndef __CORDIC_H_ ++#define __CORDIC_H_ ++ ++#include ++ ++/** ++ * struct cordic_iq - i/q coordinate. ++ * ++ * @i: real part of coordinate (in phase). ++ * @q: imaginary part of coordinate (quadrature). ++ */ ++struct cordic_iq { ++ s32 i; ++ s32 q; ++}; ++ ++/** ++ * cordic_calc_iq() - calculates the i/q coordinate for given angle. ++ * ++ * @theta: angle in degrees for which i/q coordinate is to be calculated. ++ * @coord: function output parameter holding the i/q coordinate. ++ * ++ * The function calculates the i/q coordinate for a given angle using ++ * cordic algorithm. The coordinate consists of a real (i) and an ++ * imaginary (q) part. The real part is essentially the cosine of the ++ * angle and the imaginary part is the sine of the angle. The returned ++ * values are scaled by 2^16 for precision. The range for theta is ++ * for -180 degrees to +180 degrees. Passed values outside this range are ++ * converted before doing the actual calculation. ++ */ ++#define cordic_calc_iq LINUX_BACKPORT(cordic_calc_iq) ++struct cordic_iq cordic_calc_iq(s32 theta); ++ ++#endif /* __CORDIC_H_ */ ++#endif /* LINUX_VERSION_CODE > KERNEL_VERSION(3,1,0)) */ ++#endif /* _BACKPORT_LINUX_CORDIC_H */ diff --cc compat/include/linux/crc8.h index 000000000000,000000000000..f0a92ef16a5c new file mode 100644 --- /dev/null +++ b/compat/include/linux/crc8.h @@@ -1,0 -1,0 +1,104 @@@ ++/* ++ * Copyright (c) 2011 Broadcom Corporation ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ */ ++#ifndef __CRC8_H_ ++#define __CRC8_H_ ++ ++#include ++ ++/* see usage of this value in crc8() description */ ++#define CRC8_INIT_VALUE 0xFF ++ ++/* ++ * Return value of crc8() indicating valid message+crc. This is true ++ * if a CRC is inverted before transmission. The CRC computed over the ++ * whole received bitstream is _table[x], where x is the bit pattern ++ * of the modification (almost always 0xff). ++ */ ++#define CRC8_GOOD_VALUE(_table) (_table[0xFF]) ++ ++/* required table size for crc8 algorithm */ ++#define CRC8_TABLE_SIZE 256 ++ ++/* helper macro assuring right table size is used */ ++#define DECLARE_CRC8_TABLE(_table) \ ++ static u8 _table[CRC8_TABLE_SIZE] ++ ++/** ++ * crc8_populate_lsb - fill crc table for given polynomial in regular bit order. ++ * ++ * @table: table to be filled. ++ * @polynomial: polynomial for which table is to be filled. ++ * ++ * This function fills the provided table according the polynomial provided for ++ * regular bit order (lsb first). Polynomials in CRC algorithms are typically ++ * represented as shown below. ++ * ++ * poly = x^8 + x^7 + x^6 + x^4 + x^2 + 1 ++ * ++ * For lsb first direction x^7 maps to the lsb. So the polynomial is as below. ++ * ++ * - lsb first: poly = 10101011(1) = 0xAB ++ */ ++#define crc8_populate_lsb LINUX_BACKPORT(crc8_populate_lsb) ++void crc8_populate_lsb(u8 table[CRC8_TABLE_SIZE], u8 polynomial); ++ ++/** ++ * crc8_populate_msb - fill crc table for given polynomial in reverse bit order. ++ * ++ * @table: table to be filled. ++ * @polynomial: polynomial for which table is to be filled. ++ * ++ * This function fills the provided table according the polynomial provided for ++ * reverse bit order (msb first). Polynomials in CRC algorithms are typically ++ * represented as shown below. ++ * ++ * poly = x^8 + x^7 + x^6 + x^4 + x^2 + 1 ++ * ++ * For msb first direction x^7 maps to the msb. So the polynomial is as below. ++ * ++ * - msb first: poly = (1)11010101 = 0xD5 ++ */ ++#define crc8_populate_msb LINUX_BACKPORT(crc8_populate_msb) ++void crc8_populate_msb(u8 table[CRC8_TABLE_SIZE], u8 polynomial); ++ ++/** ++ * crc8() - calculate a crc8 over the given input data. ++ * ++ * @table: crc table used for calculation. ++ * @pdata: pointer to data buffer. ++ * @nbytes: number of bytes in data buffer. ++ * @crc: previous returned crc8 value. ++ * ++ * The CRC8 is calculated using the polynomial given in crc8_populate_msb() ++ * or crc8_populate_lsb(). ++ * ++ * The caller provides the initial value (either %CRC8_INIT_VALUE ++ * or the previous returned value) to allow for processing of ++ * discontiguous blocks of data. When generating the CRC the ++ * caller is responsible for complementing the final return value ++ * and inserting it into the byte stream. When validating a byte ++ * stream (including CRC8), a final return value of %CRC8_GOOD_VALUE ++ * indicates the byte stream data can be considered valid. ++ * ++ * Reference: ++ * "A Painless Guide to CRC Error Detection Algorithms", ver 3, Aug 1993 ++ * Williams, Ross N., rossross.net ++ * (see URL http://www.ross.net/crc/download/crc_v3.txt). ++ */ ++#define crc8 LINUX_BACKPORT(crc8) ++u8 crc8(const u8 table[CRC8_TABLE_SIZE], u8 *pdata, size_t nbytes, u8 crc); ++ ++#endif /* __CRC8_H_ */ diff --cc compat/include/linux/export.h index 000000000000,000000000000..f7842b7a582d new file mode 100644 --- /dev/null +++ b/compat/include/linux/export.h @@@ -1,0 -1,0 +1,12 @@@ ++#ifndef _COMPAT_LINUX_EXPORT_H ++#define _COMPAT_LINUX_EXPORT_H 1 ++ ++#include ++ ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0)) ++#include_next ++#else ++#include ++#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0)) */ ++ ++#endif /* _COMPAT_LINUX_EXPORT_H */ diff --cc compat/include/linux/gpio.h index 000000000000,000000000000..d31e14ee00ba new file mode 100644 --- /dev/null +++ b/compat/include/linux/gpio.h @@@ -1,0 -1,0 +1,10 @@@ ++#ifndef _COMPAT_LINUX_GPIO_H ++#define _COMPAT_LINUX_GPIO_H 1 ++ ++#include ++ ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,25)) ++#include_next ++#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,25)) */ ++ ++#endif /* _COMPAT_LINUX_GPIO_H */ diff --cc compat/include/linux/kfifo.h index 000000000000,000000000000..398b00d0196c new file mode 100644 --- /dev/null +++ b/compat/include/linux/kfifo.h @@@ -1,0 -1,0 +1,877 @@@ ++#include ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)) ++#include_next ++#else ++/* ++ * A generic kernel FIFO implementation ++ * ++ * Copyright (C) 2009/2010 Stefani Seibold ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++ * ++ */ ++ ++#ifndef _LINUX_KFIFO_H ++#define _LINUX_KFIFO_H ++ ++/* ++ * How to porting drivers to the new generic FIFO API: ++ * ++ * - Modify the declaration of the "struct kfifo *" object into a ++ * in-place "struct kfifo" object ++ * - Init the in-place object with kfifo_alloc() or kfifo_init() ++ * Note: The address of the in-place "struct kfifo" object must be ++ * passed as the first argument to this functions ++ * - Replace the use of __kfifo_put into kfifo_in and __kfifo_get ++ * into kfifo_out ++ * - Replace the use of kfifo_put into kfifo_in_spinlocked and kfifo_get ++ * into kfifo_out_spinlocked ++ * Note: the spinlock pointer formerly passed to kfifo_init/kfifo_alloc ++ * must be passed now to the kfifo_in_spinlocked and kfifo_out_spinlocked ++ * as the last parameter ++ * - The formerly __kfifo_* functions are renamed into kfifo_* ++ */ ++ ++/* ++ * Note about locking : There is no locking required until only * one reader ++ * and one writer is using the fifo and no kfifo_reset() will be * called ++ * kfifo_reset_out() can be safely used, until it will be only called ++ * in the reader thread. ++ * For multiple writer and one reader there is only a need to lock the writer. ++ * And vice versa for only one writer and multiple reader there is only a need ++ * to lock the reader. ++ */ ++ ++#include ++#include ++#include ++#include ++ ++struct __kfifo { ++ unsigned int in; ++ unsigned int out; ++ unsigned int mask; ++ unsigned int esize; ++ void *data; ++}; ++ ++#define __STRUCT_KFIFO_COMMON(datatype, recsize, ptrtype) \ ++ union { \ ++ struct __kfifo kfifo; \ ++ datatype *type; \ ++ char (*rectype)[recsize]; \ ++ ptrtype *ptr; \ ++ const ptrtype *ptr_const; \ ++ } ++ ++#define __STRUCT_KFIFO(type, size, recsize, ptrtype) \ ++{ \ ++ __STRUCT_KFIFO_COMMON(type, recsize, ptrtype); \ ++ type buf[((size < 2) || (size & (size - 1))) ? -1 : size]; \ ++} ++ ++#define STRUCT_KFIFO(type, size) \ ++ struct __STRUCT_KFIFO(type, size, 0, type) ++ ++#define __STRUCT_KFIFO_PTR(type, recsize, ptrtype) \ ++{ \ ++ __STRUCT_KFIFO_COMMON(type, recsize, ptrtype); \ ++ type buf[0]; \ ++} ++ ++#define STRUCT_KFIFO_PTR(type) \ ++ struct __STRUCT_KFIFO_PTR(type, 0, type) ++ ++/* ++ * define compatibility "struct kfifo" for dynamic allocated fifos ++ */ ++struct kfifo __STRUCT_KFIFO_PTR(unsigned char, 0, void); ++ ++#define STRUCT_KFIFO_REC_1(size) \ ++ struct __STRUCT_KFIFO(unsigned char, size, 1, void) ++ ++#define STRUCT_KFIFO_REC_2(size) \ ++ struct __STRUCT_KFIFO(unsigned char, size, 2, void) ++ ++/* ++ * define kfifo_rec types ++ */ ++struct kfifo_rec_ptr_1 __STRUCT_KFIFO_PTR(unsigned char, 1, void); ++struct kfifo_rec_ptr_2 __STRUCT_KFIFO_PTR(unsigned char, 2, void); ++ ++/* ++ * helper macro to distinguish between real in place fifo where the fifo ++ * array is a part of the structure and the fifo type where the array is ++ * outside of the fifo structure. ++ */ ++#define __is_kfifo_ptr(fifo) (sizeof(*fifo) == sizeof(struct __kfifo)) ++ ++/** ++ * DECLARE_KFIFO_PTR - macro to declare a fifo pointer object ++ * @fifo: name of the declared fifo ++ * @type: type of the fifo elements ++ */ ++#define DECLARE_KFIFO_PTR(fifo, type) STRUCT_KFIFO_PTR(type) fifo ++ ++/** ++ * DECLARE_KFIFO - macro to declare a fifo object ++ * @fifo: name of the declared fifo ++ * @type: type of the fifo elements ++ * @size: the number of elements in the fifo, this must be a power of 2 ++ */ ++#define DECLARE_KFIFO(fifo, type, size) STRUCT_KFIFO(type, size) fifo ++ ++/** ++ * INIT_KFIFO - Initialize a fifo declared by DECLARE_KFIFO ++ * @fifo: name of the declared fifo datatype ++ */ ++#define INIT_KFIFO(fifo) \ ++(void)({ \ ++ typeof(&(fifo)) __tmp = &(fifo); \ ++ struct __kfifo *__kfifo = &__tmp->kfifo; \ ++ __kfifo->in = 0; \ ++ __kfifo->out = 0; \ ++ __kfifo->mask = __is_kfifo_ptr(__tmp) ? 0 : ARRAY_SIZE(__tmp->buf) - 1;\ ++ __kfifo->esize = sizeof(*__tmp->buf); \ ++ __kfifo->data = __is_kfifo_ptr(__tmp) ? NULL : __tmp->buf; \ ++}) ++ ++/** ++ * DEFINE_KFIFO - macro to define and initialize a fifo ++ * @fifo: name of the declared fifo datatype ++ * @type: type of the fifo elements ++ * @size: the number of elements in the fifo, this must be a power of 2 ++ * ++ * Note: the macro can be used for global and local fifo data type variables. ++ */ ++#define DEFINE_KFIFO(fifo, type, size) \ ++ DECLARE_KFIFO(fifo, type, size) = \ ++ (typeof(fifo)) { \ ++ { \ ++ { \ ++ .in = 0, \ ++ .out = 0, \ ++ .mask = __is_kfifo_ptr(&(fifo)) ? \ ++ 0 : \ ++ ARRAY_SIZE((fifo).buf) - 1, \ ++ .esize = sizeof(*(fifo).buf), \ ++ .data = __is_kfifo_ptr(&(fifo)) ? \ ++ NULL : \ ++ (fifo).buf, \ ++ } \ ++ } \ ++ } ++ ++ ++static inline unsigned int __must_check ++__kfifo_uint_must_check_helper(unsigned int val) ++{ ++ return val; ++} ++ ++static inline int __must_check ++__kfifo_int_must_check_helper(int val) ++{ ++ return val; ++} ++ ++#define __kfifo_alloc LINUX_BACKPORT(__kfifo_alloc) ++extern int __kfifo_alloc(struct __kfifo *fifo, unsigned int size, ++ size_t esize, gfp_t gfp_mask); ++#define __kfifo_free LINUX_BACKPORT(__kfifo_free) ++extern void __kfifo_free(struct __kfifo *fifo); ++ ++#define __kfifo_init LINUX_BACKPORT(__kfifo_init) ++extern int __kfifo_init(struct __kfifo *fifo, void *buffer, ++ unsigned int size, size_t esize); ++ ++#define __kfifo_in LINUX_BACKPORT(__kfifo_in) ++extern unsigned int __kfifo_in(struct __kfifo *fifo, ++ const void *buf, unsigned int len); ++ ++#define __kfifo_out LINUX_BACKPORT(__kfifo_out) ++extern unsigned int __kfifo_out(struct __kfifo *fifo, ++ void *buf, unsigned int len); ++ ++#define __kfifo_from_user LINUX_BACKPORT(__kfifo_from_user) ++extern int __kfifo_from_user(struct __kfifo *fifo, ++ const void __user *from, unsigned long len, unsigned int *copied); ++ ++#define __kfifo_to_user LINUX_BACKPORT(__kfifo_to_user) ++extern int __kfifo_to_user(struct __kfifo *fifo, ++ void __user *to, unsigned long len, unsigned int *copied); ++ ++#define __kfifo_dma_in_prepare LINUX_BACKPORT(__kfifo_dma_in_prepare) ++extern unsigned int __kfifo_dma_in_prepare(struct __kfifo *fifo, ++ struct scatterlist *sgl, int nents, unsigned int len); ++ ++#define __kfifo_dma_out_prepare LINUX_BACKPORT(__kfifo_dma_out_prepare) ++extern unsigned int __kfifo_dma_out_prepare(struct __kfifo *fifo, ++ struct scatterlist *sgl, int nents, unsigned int len); ++ ++#define __kfifo_out_peek LINUX_BACKPORT(__kfifo_out_peek) ++extern unsigned int __kfifo_out_peek(struct __kfifo *fifo, ++ void *buf, unsigned int len); ++ ++#define __kfifo_in_r LINUX_BACKPORT(__kfifo_in_r) ++extern unsigned int __kfifo_in_r(struct __kfifo *fifo, ++ const void *buf, unsigned int len, size_t recsize); ++ ++#define __kfifo_out_r LINUX_BACKPORT(__kfifo_out_r) ++extern unsigned int __kfifo_out_r(struct __kfifo *fifo, ++ void *buf, unsigned int len, size_t recsize); ++ ++#define __kfifo_from_user_r LINUX_BACKPORT(__kfifo_from_user_r) ++extern int __kfifo_from_user_r(struct __kfifo *fifo, ++ const void __user *from, unsigned long len, unsigned int *copied, ++ size_t recsize); ++ ++#define __kfifo_to_user_r LINUX_BACKPORT(__kfifo_to_user_r) ++extern int __kfifo_to_user_r(struct __kfifo *fifo, void __user *to, ++ unsigned long len, unsigned int *copied, size_t recsize); ++ ++#define __kfifo_dma_in_prepare_r LINUX_BACKPORT(__kfifo_dma_in_prepare_r) ++extern unsigned int __kfifo_dma_in_prepare_r(struct __kfifo *fifo, ++ struct scatterlist *sgl, int nents, unsigned int len, size_t recsize); ++ ++#define __kfifo_dma_in_finish_r LINUX_BACKPORT(__kfifo_dma_in_finish_r) ++extern void __kfifo_dma_in_finish_r(struct __kfifo *fifo, ++ unsigned int len, size_t recsize); ++ ++#define __kfifo_dma_out_prepare_r LINUX_BACKPORT(__kfifo_dma_out_prepare_r) ++extern unsigned int __kfifo_dma_out_prepare_r(struct __kfifo *fifo, ++ struct scatterlist *sgl, int nents, unsigned int len, size_t recsize); ++ ++#define __kfifo_dma_out_finish_r LINUX_BACKPORT(__kfifo_dma_out_finish_r) ++extern void __kfifo_dma_out_finish_r(struct __kfifo *fifo, size_t recsize); ++ ++#define __kfifo_len_r LINUX_BACKPORT(__kfifo_len_r) ++extern unsigned int __kfifo_len_r(struct __kfifo *fifo, size_t recsize); ++ ++#define __kfifo_skip_r LINUX_BACKPORT(__kfifo_skip_r) ++extern void __kfifo_skip_r(struct __kfifo *fifo, size_t recsize); ++ ++#define __kfifo_out_peek_r LINUX_BACKPORT(__kfifo_out_peek_r) ++extern unsigned int __kfifo_out_peek_r(struct __kfifo *fifo, ++ void *buf, unsigned int len, size_t recsize); ++ ++#define __kfifo_max_r LINUX_BACKPORT(__kfifo_max_r) ++extern unsigned int __kfifo_max_r(unsigned int len, size_t recsize); ++ ++/** ++ * kfifo_initialized - Check if the fifo is initialized ++ * @fifo: address of the fifo to check ++ * ++ * Return %true if fifo is initialized, otherwise %false. ++ * Assumes the fifo was 0 before. ++ */ ++#define kfifo_initialized(fifo) ((fifo)->kfifo.mask) ++ ++/** ++ * kfifo_esize - returns the size of the element managed by the fifo ++ * @fifo: address of the fifo to be used ++ */ ++#define kfifo_esize(fifo) ((fifo)->kfifo.esize) ++ ++/** ++ * kfifo_recsize - returns the size of the record length field ++ * @fifo: address of the fifo to be used ++ */ ++#define kfifo_recsize(fifo) (sizeof(*(fifo)->rectype)) ++ ++/** ++ * kfifo_size - returns the size of the fifo in elements ++ * @fifo: address of the fifo to be used ++ */ ++#define kfifo_size(fifo) ((fifo)->kfifo.mask + 1) ++ ++/** ++ * kfifo_reset - removes the entire fifo content ++ * @fifo: address of the fifo to be used ++ * ++ * Note: usage of kfifo_reset() is dangerous. It should be only called when the ++ * fifo is exclusived locked or when it is secured that no other thread is ++ * accessing the fifo. ++ */ ++#define kfifo_reset(fifo) \ ++(void)({ \ ++ typeof((fifo) + 1) __tmp = (fifo); \ ++ __tmp->kfifo.in = __tmp->kfifo.out = 0; \ ++}) ++ ++/** ++ * kfifo_reset_out - skip fifo content ++ * @fifo: address of the fifo to be used ++ * ++ * Note: The usage of kfifo_reset_out() is safe until it will be only called ++ * from the reader thread and there is only one concurrent reader. Otherwise ++ * it is dangerous and must be handled in the same way as kfifo_reset(). ++ */ ++#define kfifo_reset_out(fifo) \ ++(void)({ \ ++ typeof((fifo) + 1) __tmp = (fifo); \ ++ __tmp->kfifo.out = __tmp->kfifo.in; \ ++}) ++ ++/** ++ * kfifo_len - returns the number of used elements in the fifo ++ * @fifo: address of the fifo to be used ++ */ ++#define kfifo_len(fifo) \ ++({ \ ++ typeof((fifo) + 1) __tmpl = (fifo); \ ++ __tmpl->kfifo.in - __tmpl->kfifo.out; \ ++}) ++ ++/** ++ * kfifo_is_empty - returns true if the fifo is empty ++ * @fifo: address of the fifo to be used ++ */ ++#define kfifo_is_empty(fifo) \ ++({ \ ++ typeof((fifo) + 1) __tmpq = (fifo); \ ++ __tmpq->kfifo.in == __tmpq->kfifo.out; \ ++}) ++ ++/** ++ * kfifo_is_full - returns true if the fifo is full ++ * @fifo: address of the fifo to be used ++ */ ++#define kfifo_is_full(fifo) \ ++({ \ ++ typeof((fifo) + 1) __tmpq = (fifo); \ ++ kfifo_len(__tmpq) > __tmpq->kfifo.mask; \ ++}) ++ ++/** ++ * kfifo_avail - returns the number of unused elements in the fifo ++ * @fifo: address of the fifo to be used ++ */ ++#define kfifo_avail(fifo) \ ++__kfifo_uint_must_check_helper( \ ++({ \ ++ typeof((fifo) + 1) __tmpq = (fifo); \ ++ const size_t __recsize = sizeof(*__tmpq->rectype); \ ++ unsigned int __avail = kfifo_size(__tmpq) - kfifo_len(__tmpq); \ ++ (__recsize) ? ((__avail <= __recsize) ? 0 : \ ++ __kfifo_max_r(__avail - __recsize, __recsize)) : \ ++ __avail; \ ++}) \ ++) ++ ++/** ++ * kfifo_skip - skip output data ++ * @fifo: address of the fifo to be used ++ */ ++#define kfifo_skip(fifo) \ ++(void)({ \ ++ typeof((fifo) + 1) __tmp = (fifo); \ ++ const size_t __recsize = sizeof(*__tmp->rectype); \ ++ struct __kfifo *__kfifo = &__tmp->kfifo; \ ++ if (__recsize) \ ++ __kfifo_skip_r(__kfifo, __recsize); \ ++ else \ ++ __kfifo->out++; \ ++}) ++ ++/** ++ * kfifo_peek_len - gets the size of the next fifo record ++ * @fifo: address of the fifo to be used ++ * ++ * This function returns the size of the next fifo record in number of bytes. ++ */ ++#define kfifo_peek_len(fifo) \ ++__kfifo_uint_must_check_helper( \ ++({ \ ++ typeof((fifo) + 1) __tmp = (fifo); \ ++ const size_t __recsize = sizeof(*__tmp->rectype); \ ++ struct __kfifo *__kfifo = &__tmp->kfifo; \ ++ (!__recsize) ? kfifo_len(__tmp) * sizeof(*__tmp->type) : \ ++ __kfifo_len_r(__kfifo, __recsize); \ ++}) \ ++) ++ ++/** ++ * kfifo_alloc - dynamically allocates a new fifo buffer ++ * @fifo: pointer to the fifo ++ * @size: the number of elements in the fifo, this must be a power of 2 ++ * @gfp_mask: get_free_pages mask, passed to kmalloc() ++ * ++ * This macro dynamically allocates a new fifo buffer. ++ * ++ * The numer of elements will be rounded-up to a power of 2. ++ * The fifo will be release with kfifo_free(). ++ * Return 0 if no error, otherwise an error code. ++ */ ++#define kfifo_alloc(fifo, size, gfp_mask) \ ++__kfifo_int_must_check_helper( \ ++({ \ ++ typeof((fifo) + 1) __tmp = (fifo); \ ++ struct __kfifo *__kfifo = &__tmp->kfifo; \ ++ __is_kfifo_ptr(__tmp) ? \ ++ __kfifo_alloc(__kfifo, size, sizeof(*__tmp->type), gfp_mask) : \ ++ -EINVAL; \ ++}) \ ++) ++ ++/** ++ * kfifo_free - frees the fifo ++ * @fifo: the fifo to be freed ++ */ ++#define kfifo_free(fifo) \ ++({ \ ++ typeof((fifo) + 1) __tmp = (fifo); \ ++ struct __kfifo *__kfifo = &__tmp->kfifo; \ ++ if (__is_kfifo_ptr(__tmp)) \ ++ __kfifo_free(__kfifo); \ ++}) ++ ++/** ++ * kfifo_init - initialize a fifo using a preallocated buffer ++ * @fifo: the fifo to assign the buffer ++ * @buffer: the preallocated buffer to be used ++ * @size: the size of the internal buffer, this have to be a power of 2 ++ * ++ * This macro initialize a fifo using a preallocated buffer. ++ * ++ * The numer of elements will be rounded-up to a power of 2. ++ * Return 0 if no error, otherwise an error code. ++ */ ++#define kfifo_init(fifo, buffer, size) \ ++({ \ ++ typeof((fifo) + 1) __tmp = (fifo); \ ++ struct __kfifo *__kfifo = &__tmp->kfifo; \ ++ __is_kfifo_ptr(__tmp) ? \ ++ __kfifo_init(__kfifo, buffer, size, sizeof(*__tmp->type)) : \ ++ -EINVAL; \ ++}) ++ ++/** ++ * kfifo_put - put data into the fifo ++ * @fifo: address of the fifo to be used ++ * @val: the data to be added ++ * ++ * This macro copies the given value into the fifo. ++ * It returns 0 if the fifo was full. Otherwise it returns the number ++ * processed elements. ++ * ++ * Note that with only one concurrent reader and one concurrent ++ * writer, you don't need extra locking to use these macro. ++ */ ++#define kfifo_put(fifo, val) \ ++({ \ ++ typeof((fifo) + 1) __tmp = (fifo); \ ++ typeof((val) + 1) __val = (val); \ ++ unsigned int __ret; \ ++ const size_t __recsize = sizeof(*__tmp->rectype); \ ++ struct __kfifo *__kfifo = &__tmp->kfifo; \ ++ if (0) { \ ++ typeof(__tmp->ptr_const) __dummy __attribute__ ((unused)); \ ++ __dummy = (typeof(__val))NULL; \ ++ } \ ++ if (__recsize) \ ++ __ret = __kfifo_in_r(__kfifo, __val, sizeof(*__val), \ ++ __recsize); \ ++ else { \ ++ __ret = !kfifo_is_full(__tmp); \ ++ if (__ret) { \ ++ (__is_kfifo_ptr(__tmp) ? \ ++ ((typeof(__tmp->type))__kfifo->data) : \ ++ (__tmp->buf) \ ++ )[__kfifo->in & __tmp->kfifo.mask] = \ ++ *(typeof(__tmp->type))__val; \ ++ smp_wmb(); \ ++ __kfifo->in++; \ ++ } \ ++ } \ ++ __ret; \ ++}) ++ ++/** ++ * kfifo_get - get data from the fifo ++ * @fifo: address of the fifo to be used ++ * @val: the var where to store the data to be added ++ * ++ * This macro reads the data from the fifo. ++ * It returns 0 if the fifo was empty. Otherwise it returns the number ++ * processed elements. ++ * ++ * Note that with only one concurrent reader and one concurrent ++ * writer, you don't need extra locking to use these macro. ++ */ ++#define kfifo_get(fifo, val) \ ++__kfifo_uint_must_check_helper( \ ++({ \ ++ typeof((fifo) + 1) __tmp = (fifo); \ ++ typeof((val) + 1) __val = (val); \ ++ unsigned int __ret; \ ++ const size_t __recsize = sizeof(*__tmp->rectype); \ ++ struct __kfifo *__kfifo = &__tmp->kfifo; \ ++ if (0) \ ++ __val = (typeof(__tmp->ptr))0; \ ++ if (__recsize) \ ++ __ret = __kfifo_out_r(__kfifo, __val, sizeof(*__val), \ ++ __recsize); \ ++ else { \ ++ __ret = !kfifo_is_empty(__tmp); \ ++ if (__ret) { \ ++ *(typeof(__tmp->type))__val = \ ++ (__is_kfifo_ptr(__tmp) ? \ ++ ((typeof(__tmp->type))__kfifo->data) : \ ++ (__tmp->buf) \ ++ )[__kfifo->out & __tmp->kfifo.mask]; \ ++ smp_wmb(); \ ++ __kfifo->out++; \ ++ } \ ++ } \ ++ __ret; \ ++}) \ ++) ++ ++/** ++ * kfifo_peek - get data from the fifo without removing ++ * @fifo: address of the fifo to be used ++ * @val: the var where to store the data to be added ++ * ++ * This reads the data from the fifo without removing it from the fifo. ++ * It returns 0 if the fifo was empty. Otherwise it returns the number ++ * processed elements. ++ * ++ * Note that with only one concurrent reader and one concurrent ++ * writer, you don't need extra locking to use these macro. ++ */ ++#define kfifo_peek(fifo, val) \ ++__kfifo_uint_must_check_helper( \ ++({ \ ++ typeof((fifo) + 1) __tmp = (fifo); \ ++ typeof((val) + 1) __val = (val); \ ++ unsigned int __ret; \ ++ const size_t __recsize = sizeof(*__tmp->rectype); \ ++ struct __kfifo *__kfifo = &__tmp->kfifo; \ ++ if (0) \ ++ __val = (typeof(__tmp->ptr))NULL; \ ++ if (__recsize) \ ++ __ret = __kfifo_out_peek_r(__kfifo, __val, sizeof(*__val), \ ++ __recsize); \ ++ else { \ ++ __ret = !kfifo_is_empty(__tmp); \ ++ if (__ret) { \ ++ *(typeof(__tmp->type))__val = \ ++ (__is_kfifo_ptr(__tmp) ? \ ++ ((typeof(__tmp->type))__kfifo->data) : \ ++ (__tmp->buf) \ ++ )[__kfifo->out & __tmp->kfifo.mask]; \ ++ smp_wmb(); \ ++ } \ ++ } \ ++ __ret; \ ++}) \ ++) ++ ++/** ++ * kfifo_in - put data into the fifo ++ * @fifo: address of the fifo to be used ++ * @buf: the data to be added ++ * @n: number of elements to be added ++ * ++ * This macro copies the given buffer into the fifo and returns the ++ * number of copied elements. ++ * ++ * Note that with only one concurrent reader and one concurrent ++ * writer, you don't need extra locking to use these macro. ++ */ ++#define kfifo_in(fifo, buf, n) \ ++({ \ ++ typeof((fifo) + 1) __tmp = (fifo); \ ++ typeof((buf) + 1) __buf = (buf); \ ++ unsigned long __n = (n); \ ++ const size_t __recsize = sizeof(*__tmp->rectype); \ ++ struct __kfifo *__kfifo = &__tmp->kfifo; \ ++ if (0) { \ ++ typeof(__tmp->ptr_const) __dummy __attribute__ ((unused)); \ ++ __dummy = (typeof(__buf))NULL; \ ++ } \ ++ (__recsize) ?\ ++ __kfifo_in_r(__kfifo, __buf, __n, __recsize) : \ ++ __kfifo_in(__kfifo, __buf, __n); \ ++}) ++ ++/** ++ * kfifo_in_spinlocked - put data into the fifo using a spinlock for locking ++ * @fifo: address of the fifo to be used ++ * @buf: the data to be added ++ * @n: number of elements to be added ++ * @lock: pointer to the spinlock to use for locking ++ * ++ * This macro copies the given values buffer into the fifo and returns the ++ * number of copied elements. ++ */ ++#define kfifo_in_spinlocked(fifo, buf, n, lock) \ ++({ \ ++ unsigned long __flags; \ ++ unsigned int __ret; \ ++ spin_lock_irqsave(lock, __flags); \ ++ __ret = kfifo_in(fifo, buf, n); \ ++ spin_unlock_irqrestore(lock, __flags); \ ++ __ret; \ ++}) ++ ++/* alias for kfifo_in_spinlocked, will be removed in a future release */ ++#define kfifo_in_locked(fifo, buf, n, lock) \ ++ kfifo_in_spinlocked(fifo, buf, n, lock) ++ ++/** ++ * kfifo_out - get data from the fifo ++ * @fifo: address of the fifo to be used ++ * @buf: pointer to the storage buffer ++ * @n: max. number of elements to get ++ * ++ * This macro get some data from the fifo and return the numbers of elements ++ * copied. ++ * ++ * Note that with only one concurrent reader and one concurrent ++ * writer, you don't need extra locking to use these macro. ++ */ ++#define kfifo_out(fifo, buf, n) \ ++__kfifo_uint_must_check_helper( \ ++({ \ ++ typeof((fifo) + 1) __tmp = (fifo); \ ++ typeof((buf) + 1) __buf = (buf); \ ++ unsigned long __n = (n); \ ++ const size_t __recsize = sizeof(*__tmp->rectype); \ ++ struct __kfifo *__kfifo = &__tmp->kfifo; \ ++ if (0) { \ ++ typeof(__tmp->ptr) __dummy = NULL; \ ++ __buf = __dummy; \ ++ } \ ++ (__recsize) ?\ ++ __kfifo_out_r(__kfifo, __buf, __n, __recsize) : \ ++ __kfifo_out(__kfifo, __buf, __n); \ ++}) \ ++) ++ ++/** ++ * kfifo_out_spinlocked - get data from the fifo using a spinlock for locking ++ * @fifo: address of the fifo to be used ++ * @buf: pointer to the storage buffer ++ * @n: max. number of elements to get ++ * @lock: pointer to the spinlock to use for locking ++ * ++ * This macro get the data from the fifo and return the numbers of elements ++ * copied. ++ */ ++#define kfifo_out_spinlocked(fifo, buf, n, lock) \ ++__kfifo_uint_must_check_helper( \ ++({ \ ++ unsigned long __flags; \ ++ unsigned int __ret; \ ++ spin_lock_irqsave(lock, __flags); \ ++ __ret = kfifo_out(fifo, buf, n); \ ++ spin_unlock_irqrestore(lock, __flags); \ ++ __ret; \ ++}) \ ++) ++ ++/* alias for kfifo_out_spinlocked, will be removed in a future release */ ++#define kfifo_out_locked(fifo, buf, n, lock) \ ++ kfifo_out_spinlocked(fifo, buf, n, lock) ++ ++/** ++ * kfifo_from_user - puts some data from user space into the fifo ++ * @fifo: address of the fifo to be used ++ * @from: pointer to the data to be added ++ * @len: the length of the data to be added ++ * @copied: pointer to output variable to store the number of copied bytes ++ * ++ * This macro copies at most @len bytes from the @from into the ++ * fifo, depending of the available space and returns -EFAULT/0. ++ * ++ * Note that with only one concurrent reader and one concurrent ++ * writer, you don't need extra locking to use these macro. ++ */ ++#define kfifo_from_user(fifo, from, len, copied) \ ++__kfifo_uint_must_check_helper( \ ++({ \ ++ typeof((fifo) + 1) __tmp = (fifo); \ ++ const void __user *__from = (from); \ ++ unsigned int __len = (len); \ ++ unsigned int *__copied = (copied); \ ++ const size_t __recsize = sizeof(*__tmp->rectype); \ ++ struct __kfifo *__kfifo = &__tmp->kfifo; \ ++ (__recsize) ? \ ++ __kfifo_from_user_r(__kfifo, __from, __len, __copied, __recsize) : \ ++ __kfifo_from_user(__kfifo, __from, __len, __copied); \ ++}) \ ++) ++ ++/** ++ * kfifo_to_user - copies data from the fifo into user space ++ * @fifo: address of the fifo to be used ++ * @to: where the data must be copied ++ * @len: the size of the destination buffer ++ * @copied: pointer to output variable to store the number of copied bytes ++ * ++ * This macro copies at most @len bytes from the fifo into the ++ * @to buffer and returns -EFAULT/0. ++ * ++ * Note that with only one concurrent reader and one concurrent ++ * writer, you don't need extra locking to use these macro. ++ */ ++#define kfifo_to_user(fifo, to, len, copied) \ ++__kfifo_uint_must_check_helper( \ ++({ \ ++ typeof((fifo) + 1) __tmp = (fifo); \ ++ void __user *__to = (to); \ ++ unsigned int __len = (len); \ ++ unsigned int *__copied = (copied); \ ++ const size_t __recsize = sizeof(*__tmp->rectype); \ ++ struct __kfifo *__kfifo = &__tmp->kfifo; \ ++ (__recsize) ? \ ++ __kfifo_to_user_r(__kfifo, __to, __len, __copied, __recsize) : \ ++ __kfifo_to_user(__kfifo, __to, __len, __copied); \ ++}) \ ++) ++ ++/** ++ * kfifo_dma_in_prepare - setup a scatterlist for DMA input ++ * @fifo: address of the fifo to be used ++ * @sgl: pointer to the scatterlist array ++ * @nents: number of entries in the scatterlist array ++ * @len: number of elements to transfer ++ * ++ * This macro fills a scatterlist for DMA input. ++ * It returns the number entries in the scatterlist array. ++ * ++ * Note that with only one concurrent reader and one concurrent ++ * writer, you don't need extra locking to use these macros. ++ */ ++#define kfifo_dma_in_prepare(fifo, sgl, nents, len) \ ++({ \ ++ typeof((fifo) + 1) __tmp = (fifo); \ ++ struct scatterlist *__sgl = (sgl); \ ++ int __nents = (nents); \ ++ unsigned int __len = (len); \ ++ const size_t __recsize = sizeof(*__tmp->rectype); \ ++ struct __kfifo *__kfifo = &__tmp->kfifo; \ ++ (__recsize) ? \ ++ __kfifo_dma_in_prepare_r(__kfifo, __sgl, __nents, __len, __recsize) : \ ++ __kfifo_dma_in_prepare(__kfifo, __sgl, __nents, __len); \ ++}) ++ ++/** ++ * kfifo_dma_in_finish - finish a DMA IN operation ++ * @fifo: address of the fifo to be used ++ * @len: number of bytes to received ++ * ++ * This macro finish a DMA IN operation. The in counter will be updated by ++ * the len parameter. No error checking will be done. ++ * ++ * Note that with only one concurrent reader and one concurrent ++ * writer, you don't need extra locking to use these macros. ++ */ ++#define kfifo_dma_in_finish(fifo, len) \ ++(void)({ \ ++ typeof((fifo) + 1) __tmp = (fifo); \ ++ unsigned int __len = (len); \ ++ const size_t __recsize = sizeof(*__tmp->rectype); \ ++ struct __kfifo *__kfifo = &__tmp->kfifo; \ ++ if (__recsize) \ ++ __kfifo_dma_in_finish_r(__kfifo, __len, __recsize); \ ++ else \ ++ __kfifo->in += __len / sizeof(*__tmp->type); \ ++}) ++ ++/** ++ * kfifo_dma_out_prepare - setup a scatterlist for DMA output ++ * @fifo: address of the fifo to be used ++ * @sgl: pointer to the scatterlist array ++ * @nents: number of entries in the scatterlist array ++ * @len: number of elements to transfer ++ * ++ * This macro fills a scatterlist for DMA output which at most @len bytes ++ * to transfer. ++ * It returns the number entries in the scatterlist array. ++ * A zero means there is no space available and the scatterlist is not filled. ++ * ++ * Note that with only one concurrent reader and one concurrent ++ * writer, you don't need extra locking to use these macros. ++ */ ++#define kfifo_dma_out_prepare(fifo, sgl, nents, len) \ ++({ \ ++ typeof((fifo) + 1) __tmp = (fifo); \ ++ struct scatterlist *__sgl = (sgl); \ ++ int __nents = (nents); \ ++ unsigned int __len = (len); \ ++ const size_t __recsize = sizeof(*__tmp->rectype); \ ++ struct __kfifo *__kfifo = &__tmp->kfifo; \ ++ (__recsize) ? \ ++ __kfifo_dma_out_prepare_r(__kfifo, __sgl, __nents, __len, __recsize) : \ ++ __kfifo_dma_out_prepare(__kfifo, __sgl, __nents, __len); \ ++}) ++ ++/** ++ * kfifo_dma_out_finish - finish a DMA OUT operation ++ * @fifo: address of the fifo to be used ++ * @len: number of bytes transferd ++ * ++ * This macro finish a DMA OUT operation. The out counter will be updated by ++ * the len parameter. No error checking will be done. ++ * ++ * Note that with only one concurrent reader and one concurrent ++ * writer, you don't need extra locking to use these macros. ++ */ ++#define kfifo_dma_out_finish(fifo, len) \ ++(void)({ \ ++ typeof((fifo) + 1) __tmp = (fifo); \ ++ unsigned int __len = (len); \ ++ const size_t __recsize = sizeof(*__tmp->rectype); \ ++ struct __kfifo *__kfifo = &__tmp->kfifo; \ ++ if (__recsize) \ ++ __kfifo_dma_out_finish_r(__kfifo, __recsize); \ ++ else \ ++ __kfifo->out += __len / sizeof(*__tmp->type); \ ++}) ++ ++/** ++ * kfifo_out_peek - gets some data from the fifo ++ * @fifo: address of the fifo to be used ++ * @buf: pointer to the storage buffer ++ * @n: max. number of elements to get ++ * ++ * This macro get the data from the fifo and return the numbers of elements ++ * copied. The data is not removed from the fifo. ++ * ++ * Note that with only one concurrent reader and one concurrent ++ * writer, you don't need extra locking to use these macro. ++ */ ++#define kfifo_out_peek(fifo, buf, n) \ ++__kfifo_uint_must_check_helper( \ ++({ \ ++ typeof((fifo) + 1) __tmp = (fifo); \ ++ typeof((buf) + 1) __buf = (buf); \ ++ unsigned long __n = (n); \ ++ const size_t __recsize = sizeof(*__tmp->rectype); \ ++ struct __kfifo *__kfifo = &__tmp->kfifo; \ ++ if (0) { \ ++ typeof(__tmp->ptr) __dummy __attribute__ ((unused)) = NULL; \ ++ __buf = __dummy; \ ++ } \ ++ (__recsize) ? \ ++ __kfifo_out_peek_r(__kfifo, __buf, __n, __recsize) : \ ++ __kfifo_out_peek(__kfifo, __buf, __n); \ ++}) \ ++) ++#endif ++#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)) */ diff --cc compat/include/linux/kmemleak.h index 000000000000,000000000000..83bd199c2934 new file mode 100644 --- /dev/null +++ b/compat/include/linux/kmemleak.h @@@ -1,0 -1,0 +1,5 @@@ ++#include ++ ++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,30)) ++#include_next ++#endif /* (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,25)) */ diff --cc compat/include/linux/math64.h index 000000000000,000000000000..eb9e8e15225c new file mode 100644 --- /dev/null +++ b/compat/include/linux/math64.h @@@ -1,0 -1,0 +1,10 @@@ ++#ifndef _COMPAT_LINUX_MATH64_H ++#define _COMPAT_LINUX_MATH64_H 1 ++ ++#include ++ ++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,25)) ++#include_next ++#endif /* (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,25)) */ ++ ++#endif /* _COMPAT_LINUX_MATH64_H */ diff --cc compat/include/linux/of.h index 000000000000,000000000000..c5dc87c2ef64 new file mode 100644 --- /dev/null +++ b/compat/include/linux/of.h @@@ -1,0 -1,0 +1,16 @@@ ++#ifndef _COMPAT_LINUX_OF_H ++#define _COMPAT_LINUX_OF_H 1 ++ ++#include ++ ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34)) ++#include_next ++#else ++ ++#ifdef CONFIG_OF ++#include_next ++#endif /* CONFIG_OF */ ++ ++#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34)) */ ++ ++#endif /* _COMPAT_LINUX_OF_H */ diff --cc compat/include/linux/olpc-ec.h index 000000000000,000000000000..a5b932a75a29 new file mode 100644 --- /dev/null +++ b/compat/include/linux/olpc-ec.h @@@ -1,0 -1,0 +1,10 @@@ ++#ifndef _COMPAT_LINUX_OLPC_EC_H ++#define _COMPAT_LINUX_OLPC_EC_H ++ ++#include ++ ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) ++#include_next ++#endif /* (LINUX_VERSION_CODE > KERNEL_VERSION(3,6,0)) */ ++ ++#endif /* _COMPAT_LINUX_OLPC_EC_H */ diff --cc compat/include/linux/pci-aspm.h index 000000000000,000000000000..2bc6efb33300 new file mode 100644 --- /dev/null +++ b/compat/include/linux/pci-aspm.h @@@ -1,0 -1,0 +1,5 @@@ ++#include ++ ++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,25)) ++#include_next ++#endif /* (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,25)) */ diff --cc compat/include/linux/pm_qos.h index 000000000000,000000000000..c58c1c1f0161 new file mode 100644 --- /dev/null +++ b/compat/include/linux/pm_qos.h @@@ -1,0 -1,0 +1,12 @@@ ++#ifndef _COMPAT_LINUX_PM_QOS_H ++#define _COMPAT_LINUX_PM_QOS_H 1 ++ ++#include ++ ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0)) ++#include_next ++#else ++#include ++#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0)) */ ++ ++#endif /* _COMPAT_LINUX_PM_QOS_H */ diff --cc compat/include/linux/pm_qos_params.h index 000000000000,000000000000..4c8c89eff15c new file mode 100644 --- /dev/null +++ b/compat/include/linux/pm_qos_params.h @@@ -1,0 -1,0 +1,42 @@@ ++#include ++ ++#ifndef __COMPAT_LINUX_PM_QOS_PARAMS_H ++#define __COMPAT_LINUX_PM_QOS_PARAMS_H ++ ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,25)) ++#include_next ++#else ++/* interface for the pm_qos_power infrastructure of the linux kernel. ++ * ++ * Mark Gross ++ */ ++#include ++#include ++#include ++ ++#define PM_QOS_RESERVED 0 ++#define PM_QOS_CPU_DMA_LATENCY 1 ++#define PM_QOS_NETWORK_LATENCY 2 ++#define PM_QOS_NETWORK_THROUGHPUT 3 ++#define PM_QOS_SYSTEM_BUS_FREQ 4 ++ ++#define PM_QOS_NUM_CLASSES 5 ++#define PM_QOS_DEFAULT_VALUE -1 ++ ++#define pm_qos_add_requirement LINUX_BACKPORT(pm_qos_add_requirement) ++int pm_qos_add_requirement(int qos, char *name, s32 value); ++#define pm_qos_update_requirement LINUX_BACKPORT(pm_qos_update_requirement) ++int pm_qos_update_requirement(int qos, char *name, s32 new_value); ++#define pm_qos_remove_requirement LINUX_BACKPORT(pm_qos_remove_requirement) ++void pm_qos_remove_requirement(int qos, char *name); ++ ++#define pm_qos_requirement LINUX_BACKPORT(pm_qos_requirement) ++int pm_qos_requirement(int qos); ++ ++#define pm_qos_add_notifier LINUX_BACKPORT(pm_qos_add_notifier) ++int pm_qos_add_notifier(int qos, struct notifier_block *notifier); ++#define pm_qos_remove_notifier LINUX_BACKPORT(pm_qos_remove_notifier) ++int pm_qos_remove_notifier(int qos, struct notifier_block *notifier); ++#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,25)) */ ++ ++#endif diff --cc compat/include/linux/pm_runtime.h index 000000000000,000000000000..eec965ba0d73 new file mode 100644 --- /dev/null +++ b/compat/include/linux/pm_runtime.h @@@ -1,0 -1,0 +1,14 @@@ ++#include ++ ++#ifndef __COMPAT_LINUX_PM_RUNTIME_H ++#define __COMPAT_LINUX_PM_RUNTIME_H ++ ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32)) ++#include_next ++#else ++ ++static inline void pm_runtime_enable(struct device *dev) {} ++ ++#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32)) */ ++ ++#endif diff --cc compat/include/linux/printk.h index 000000000000,000000000000..c0822ac488ca new file mode 100644 --- /dev/null +++ b/compat/include/linux/printk.h @@@ -1,0 -1,0 +1,12 @@@ ++#ifndef _COMPAT_LINUX_PRINTK_H ++#define _COMPAT_LINUX_PRINTK_H 1 ++ ++#include ++ ++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,36)) ++#include_next ++#else ++#include ++#endif /* (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35)) */ ++ ++#endif /* _COMPAT_LINUX_PRINTK_H */ diff --cc compat/include/linux/rfkill.h index 000000000000,000000000000..d615ac9f5b73 new file mode 100644 --- /dev/null +++ b/compat/include/linux/rfkill.h @@@ -1,0 -1,0 +1,32 @@@ ++#ifndef __COMPAT_RFKILL_H ++#define __COMPAT_RFKILL_H ++ ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,31)) ++ ++#include_next ++ ++#else ++ ++#include ++ ++#undef CONFIG_RFKILL ++#undef CONFIG_RFKILL_INPUT ++#undef CONFIG_RFKILL_LEDS ++ ++#ifdef CONFIG_RFKILL_BACKPORT ++#define CONFIG_RFKILL 1 ++#endif ++ ++#ifdef CONFIG_RFKILL_BACKPORT_INPUT ++#define CONFIG_RFKILL_INPUT ++#endif ++ ++#ifdef CONFIG_RFKILL_BACKPORT_LEDS ++#define CONFIG_RFKILL_LEDS ++#endif ++ ++#include ++ ++#endif ++ ++#endif diff --cc compat/include/linux/semaphore.h index 000000000000,000000000000..78af4db376fd new file mode 100644 --- /dev/null +++ b/compat/include/linux/semaphore.h @@@ -1,0 -1,0 +1,12 @@@ ++#ifndef _COMPAT_LINUX_SEMAPHORE_H ++#define _COMPAT_LINUX_SEMAPHORE_H 1 ++ ++#include ++ ++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,25)) ++#include_next ++#else ++#include ++#endif /* (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,25)) */ ++ ++#endif /* _COMPAT_LINUX_SEMAPHORE_H */ diff --cc compat/include/linux/tracepoint.h index 000000000000,000000000000..fc44692a1d68 new file mode 100644 --- /dev/null +++ b/compat/include/linux/tracepoint.h @@@ -1,0 -1,0 +1,41 @@@ ++#ifndef _COMPAT_LINUX_TRACEPOINT_H ++#define _COMPAT_LINUX_TRACEPOINT_H 1 ++ ++#include ++ ++#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,32)) ++/* ++ * Disable all tracing for older kernels ++ * < 2.6.27 had no tracing ++ * 2.6.27 had broken tracing ++ * 2.6.28-2.6.32 didn't have anything like DECLARE_EVENT_CLASS ++ * and faking it would be extremely difficult ++ */ ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28)) ++/* ++ * For 2.6.28+ include the original tracepoint.h but override ++ * the defines new code uses to disable tracing completely. ++ */ ++#include_next ++#endif ++ ++#undef TRACE_EVENT ++#define TRACE_EVENT(name, proto, ...) \ ++static inline void trace_ ## name(proto) {} ++#undef DECLARE_EVENT_CLASS ++#define DECLARE_EVENT_CLASS(...) ++#undef DEFINE_EVENT ++#define DEFINE_EVENT(evt_class, name, proto, ...) \ ++static inline void trace_ ## name(proto) {} ++ ++#define TP_PROTO(args...) args ++#define TP_ARGS(args...) args ++#define TP_CONDITION(args...) args ++ ++#else ++/* since 2.6.33, tracing hasn't changed, so just include the kernel's file */ ++#include_next ++ ++#endif /* (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,32)) */ ++ ++#endif /* _COMPAT_LINUX_TRACEPOINT_H */ diff --cc compat/include/linux/u64_stats_sync.h index 000000000000,000000000000..f15116c28279 new file mode 100644 --- /dev/null +++ b/compat/include/linux/u64_stats_sync.h @@@ -1,0 -1,0 +1,144 @@@ ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) ++#include_next ++#else ++#ifndef _LINUX_U64_STATS_SYNC_H ++#define _LINUX_U64_STATS_SYNC_H ++ ++/* ++ * To properly implement 64bits network statistics on 32bit and 64bit hosts, ++ * we provide a synchronization point, that is a noop on 64bit or UP kernels. ++ * ++ * Key points : ++ * 1) Use a seqcount on SMP 32bits, with low overhead. ++ * 2) Whole thing is a noop on 64bit arches or UP kernels. ++ * 3) Write side must ensure mutual exclusion or one seqcount update could ++ * be lost, thus blocking readers forever. ++ * If this synchronization point is not a mutex, but a spinlock or ++ * spinlock_bh() or disable_bh() : ++ * 3.1) Write side should not sleep. ++ * 3.2) Write side should not allow preemption. ++ * 3.3) If applicable, interrupts should be disabled. ++ * ++ * 4) If reader fetches several counters, there is no guarantee the whole values ++ * are consistent (remember point 1) : this is a noop on 64bit arches anyway) ++ * ++ * 5) readers are allowed to sleep or be preempted/interrupted : They perform ++ * pure reads. But if they have to fetch many values, it's better to not allow ++ * preemptions/interruptions to avoid many retries. ++ * ++ * 6) If counter might be written by an interrupt, readers should block interrupts. ++ * (On UP, there is no seqcount_t protection, a reader allowing interrupts could ++ * read partial values) ++ * ++ * 7) For softirq uses, readers can use u64_stats_fetch_begin_bh() and ++ * u64_stats_fetch_retry_bh() helpers ++ * ++ * Usage : ++ * ++ * Stats producer (writer) should use following template granted it already got ++ * an exclusive access to counters (a lock is already taken, or per cpu ++ * data is used [in a non preemptable context]) ++ * ++ * spin_lock_bh(...) or other synchronization to get exclusive access ++ * ... ++ * u64_stats_update_begin(&stats->syncp); ++ * stats->bytes64 += len; // non atomic operation ++ * stats->packets64++; // non atomic operation ++ * u64_stats_update_end(&stats->syncp); ++ * ++ * While a consumer (reader) should use following template to get consistent ++ * snapshot for each variable (but no guarantee on several ones) ++ * ++ * u64 tbytes, tpackets; ++ * unsigned int start; ++ * ++ * do { ++ * start = u64_stats_fetch_begin(&stats->syncp); ++ * tbytes = stats->bytes64; // non atomic operation ++ * tpackets = stats->packets64; // non atomic operation ++ * } while (u64_stats_fetch_retry(&stats->syncp, start)); ++ * ++ * ++ * Example of use in drivers/net/loopback.c, using per_cpu containers, ++ * in BH disabled context. ++ */ ++#include ++ ++struct u64_stats_sync { ++#if BITS_PER_LONG==32 && defined(CONFIG_SMP) ++ seqcount_t seq; ++#endif ++}; ++ ++static inline void u64_stats_update_begin(struct u64_stats_sync *syncp) ++{ ++#if BITS_PER_LONG==32 && defined(CONFIG_SMP) ++ write_seqcount_begin(&syncp->seq); ++#endif ++} ++ ++static inline void u64_stats_update_end(struct u64_stats_sync *syncp) ++{ ++#if BITS_PER_LONG==32 && defined(CONFIG_SMP) ++ write_seqcount_end(&syncp->seq); ++#endif ++} ++ ++static inline unsigned int u64_stats_fetch_begin(const struct u64_stats_sync *syncp) ++{ ++#if BITS_PER_LONG==32 && defined(CONFIG_SMP) ++ return read_seqcount_begin(&syncp->seq); ++#else ++#if BITS_PER_LONG==32 ++ preempt_disable(); ++#endif ++ return 0; ++#endif ++} ++ ++static inline bool u64_stats_fetch_retry(const struct u64_stats_sync *syncp, ++ unsigned int start) ++{ ++#if BITS_PER_LONG==32 && defined(CONFIG_SMP) ++ return read_seqcount_retry(&syncp->seq, start); ++#else ++#if BITS_PER_LONG==32 ++ preempt_enable(); ++#endif ++ return false; ++#endif ++} ++ ++/* ++ * In case softirq handlers can update u64 counters, readers can use following helpers ++ * - SMP 32bit arches use seqcount protection, irq safe. ++ * - UP 32bit must disable BH. ++ * - 64bit have no problem atomically reading u64 values, irq safe. ++ */ ++static inline unsigned int u64_stats_fetch_begin_bh(const struct u64_stats_sync *syncp) ++{ ++#if BITS_PER_LONG==32 && defined(CONFIG_SMP) ++ return read_seqcount_begin(&syncp->seq); ++#else ++#if BITS_PER_LONG==32 ++ local_bh_disable(); ++#endif ++ return 0; ++#endif ++} ++ ++static inline bool u64_stats_fetch_retry_bh(const struct u64_stats_sync *syncp, ++ unsigned int start) ++{ ++#if BITS_PER_LONG==32 && defined(CONFIG_SMP) ++ return read_seqcount_retry(&syncp->seq, start); ++#else ++#if BITS_PER_LONG==32 ++ local_bh_enable(); ++#endif ++ return false; ++#endif ++} ++ ++#endif /* _LINUX_U64_STATS_SYNC_H */ ++#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) */ diff --cc compat/include/linux/uidgid.h index 000000000000,000000000000..ae1ed808cfd6 new file mode 100644 --- /dev/null +++ b/compat/include/linux/uidgid.h @@@ -1,0 -1,0 +1,221 @@@ ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)) ++#include_next ++#else ++ ++#ifndef _LINUX_UIDGID_H ++#define _LINUX_UIDGID_H ++ ++/* ++ * A set of types for the internal kernel types representing uids and gids. ++ * ++ * The types defined in this header allow distinguishing which uids and gids in ++ * the kernel are values used by userspace and which uid and gid values are ++ * the internal kernel values. With the addition of user namespaces the values ++ * can be different. Using the type system makes it possible for the compiler ++ * to detect when we overlook these differences. ++ * ++ */ ++#include ++#include ++ ++struct user_namespace; ++extern struct user_namespace init_user_ns; ++ ++#ifdef CONFIG_UIDGID_STRICT_TYPE_CHECKS ++ ++typedef struct { ++ uid_t val; ++} kuid_t; ++ ++ ++typedef struct { ++ gid_t val; ++} kgid_t; ++ ++#define KUIDT_INIT(value) (kuid_t){ value } ++#define KGIDT_INIT(value) (kgid_t){ value } ++ ++static inline uid_t __kuid_val(kuid_t uid) ++{ ++ return uid.val; ++} ++ ++static inline gid_t __kgid_val(kgid_t gid) ++{ ++ return gid.val; ++} ++ ++#else ++ ++typedef uid_t kuid_t; ++typedef gid_t kgid_t; ++ ++static inline uid_t __kuid_val(kuid_t uid) ++{ ++ return uid; ++} ++ ++static inline gid_t __kgid_val(kgid_t gid) ++{ ++ return gid; ++} ++ ++#define KUIDT_INIT(value) ((kuid_t) value ) ++#define KGIDT_INIT(value) ((kgid_t) value ) ++ ++#endif ++ ++#define GLOBAL_ROOT_UID KUIDT_INIT(0) ++#define GLOBAL_ROOT_GID KGIDT_INIT(0) ++ ++#define INVALID_UID KUIDT_INIT(-1) ++#define INVALID_GID KGIDT_INIT(-1) ++ ++static inline bool uid_eq(kuid_t left, kuid_t right) ++{ ++ return __kuid_val(left) == __kuid_val(right); ++} ++ ++static inline bool gid_eq(kgid_t left, kgid_t right) ++{ ++ return __kgid_val(left) == __kgid_val(right); ++} ++ ++static inline bool uid_gt(kuid_t left, kuid_t right) ++{ ++ return __kuid_val(left) > __kuid_val(right); ++} ++ ++static inline bool gid_gt(kgid_t left, kgid_t right) ++{ ++ return __kgid_val(left) > __kgid_val(right); ++} ++ ++static inline bool uid_gte(kuid_t left, kuid_t right) ++{ ++ return __kuid_val(left) >= __kuid_val(right); ++} ++ ++static inline bool gid_gte(kgid_t left, kgid_t right) ++{ ++ return __kgid_val(left) >= __kgid_val(right); ++} ++ ++static inline bool uid_lt(kuid_t left, kuid_t right) ++{ ++ return __kuid_val(left) < __kuid_val(right); ++} ++ ++static inline bool gid_lt(kgid_t left, kgid_t right) ++{ ++ return __kgid_val(left) < __kgid_val(right); ++} ++ ++static inline bool uid_lte(kuid_t left, kuid_t right) ++{ ++ return __kuid_val(left) <= __kuid_val(right); ++} ++ ++static inline bool gid_lte(kgid_t left, kgid_t right) ++{ ++ return __kgid_val(left) <= __kgid_val(right); ++} ++ ++static inline bool uid_valid(kuid_t uid) ++{ ++ return !uid_eq(uid, INVALID_UID); ++} ++ ++static inline bool gid_valid(kgid_t gid) ++{ ++ return !gid_eq(gid, INVALID_GID); ++} ++ ++#ifdef CONFIG_USER_NS ++ ++#define make_kuid LINUX_BACKPORT(make_kuid) ++extern kuid_t make_kuid(struct user_namespace *from, uid_t uid); ++#define make_kgid LINUX_BACKPORT(make_kgid) ++extern kgid_t make_kgid(struct user_namespace *from, gid_t gid); ++ ++#define from_kuid LINUX_BACKPORT(from_kuid) ++extern uid_t from_kuid(struct user_namespace *to, kuid_t uid); ++#define from_kgid LINUX_BACKPORT(from_kgid) ++extern gid_t from_kgid(struct user_namespace *to, kgid_t gid); ++#define from_kuid_munged LINUX_BACKPORT(from_kuid_munged) ++extern uid_t from_kuid_munged(struct user_namespace *to, kuid_t uid); ++#define from_kgid_munged LINUX_BACKPORT(from_kgid_munged) ++extern gid_t from_kgid_munged(struct user_namespace *to, kgid_t gid); ++ ++#define kuid_has_mapping LINUX_BACKPORT(kuid_has_mapping) ++static inline bool kuid_has_mapping(struct user_namespace *ns, kuid_t uid) ++{ ++ return from_kuid(ns, uid) != (uid_t) -1; ++} ++ ++#define kgid_has_mapping LINUX_BACKPORT(kgid_has_mapping) ++static inline bool kgid_has_mapping(struct user_namespace *ns, kgid_t gid) ++{ ++ return from_kgid(ns, gid) != (gid_t) -1; ++} ++ ++#else ++ ++#define make_kuid LINUX_BACKPORT(make_kuid) ++static inline kuid_t make_kuid(struct user_namespace *from, uid_t uid) ++{ ++ return KUIDT_INIT(uid); ++} ++ ++#define make_kgid LINUX_BACKPORT(make_kgid) ++static inline kgid_t make_kgid(struct user_namespace *from, gid_t gid) ++{ ++ return KGIDT_INIT(gid); ++} ++ ++#define from_kuid LINUX_BACKPORT(from_kuid) ++static inline uid_t from_kuid(struct user_namespace *to, kuid_t kuid) ++{ ++ return __kuid_val(kuid); ++} ++ ++#define from_kgid LINUX_BACKPORT(from_kgid) ++static inline gid_t from_kgid(struct user_namespace *to, kgid_t kgid) ++{ ++ return __kgid_val(kgid); ++} ++ ++#define from_kuid_munged LINUX_BACKPORT(from_kuid_munged) ++static inline uid_t from_kuid_munged(struct user_namespace *to, kuid_t kuid) ++{ ++ uid_t uid = from_kuid(to, kuid); ++ if (uid == (uid_t)-1) ++ uid = overflowuid; ++ return uid; ++} ++ ++#define from_kgid_munged LINUX_BACKPORT(from_kgid_munged) ++static inline gid_t from_kgid_munged(struct user_namespace *to, kgid_t kgid) ++{ ++ gid_t gid = from_kgid(to, kgid); ++ if (gid == (gid_t)-1) ++ gid = overflowgid; ++ return gid; ++} ++ ++#define kuid_has_mapping LINUX_BACKPORT(kuid_has_mapping) ++static inline bool kuid_has_mapping(struct user_namespace *ns, kuid_t uid) ++{ ++ return true; ++} ++ ++#define kgid_has_mapping LINUX_BACKPORT(kgid_has_mapping) ++static inline bool kgid_has_mapping(struct user_namespace *ns, kgid_t gid) ++{ ++ return true; ++} ++ ++#endif /* CONFIG_USER_NS */ ++ ++#endif /* _LINUX_UIDGID_H */ ++#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0) */ diff --cc compat/include/linux/unaligned/access_ok.h index 000000000000,000000000000..99c1b4d20b0f new file mode 100644 --- /dev/null +++ b/compat/include/linux/unaligned/access_ok.h @@@ -1,0 -1,0 +1,67 @@@ ++#ifndef _LINUX_UNALIGNED_ACCESS_OK_H ++#define _LINUX_UNALIGNED_ACCESS_OK_H ++ ++#include ++#include ++ ++static inline u16 get_unaligned_le16(const void *p) ++{ ++ return le16_to_cpup((__le16 *)p); ++} ++ ++static inline u32 get_unaligned_le32(const void *p) ++{ ++ return le32_to_cpup((__le32 *)p); ++} ++ ++static inline u64 get_unaligned_le64(const void *p) ++{ ++ return le64_to_cpup((__le64 *)p); ++} ++ ++static inline u16 get_unaligned_be16(const void *p) ++{ ++ return be16_to_cpup((__be16 *)p); ++} ++ ++static inline u32 get_unaligned_be32(const void *p) ++{ ++ return be32_to_cpup((__be32 *)p); ++} ++ ++static inline u64 get_unaligned_be64(const void *p) ++{ ++ return be64_to_cpup((__be64 *)p); ++} ++ ++static inline void put_unaligned_le16(u16 val, void *p) ++{ ++ *((__le16 *)p) = cpu_to_le16(val); ++} ++ ++static inline void put_unaligned_le32(u32 val, void *p) ++{ ++ *((__le32 *)p) = cpu_to_le32(val); ++} ++ ++static inline void put_unaligned_le64(u64 val, void *p) ++{ ++ *((__le64 *)p) = cpu_to_le64(val); ++} ++ ++static inline void put_unaligned_be16(u16 val, void *p) ++{ ++ *((__be16 *)p) = cpu_to_be16(val); ++} ++ ++static inline void put_unaligned_be32(u32 val, void *p) ++{ ++ *((__be32 *)p) = cpu_to_be32(val); ++} ++ ++static inline void put_unaligned_be64(u64 val, void *p) ++{ ++ *((__be64 *)p) = cpu_to_be64(val); ++} ++ ++#endif /* _LINUX_UNALIGNED_ACCESS_OK_H */ diff --cc compat/include/linux/unaligned/be_byteshift.h index 000000000000,000000000000..9356b24223ac new file mode 100644 --- /dev/null +++ b/compat/include/linux/unaligned/be_byteshift.h @@@ -1,0 -1,0 +1,70 @@@ ++#ifndef _LINUX_UNALIGNED_BE_BYTESHIFT_H ++#define _LINUX_UNALIGNED_BE_BYTESHIFT_H ++ ++#include ++ ++static inline u16 __get_unaligned_be16(const u8 *p) ++{ ++ return p[0] << 8 | p[1]; ++} ++ ++static inline u32 __get_unaligned_be32(const u8 *p) ++{ ++ return p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3]; ++} ++ ++static inline u64 __get_unaligned_be64(const u8 *p) ++{ ++ return (u64)__get_unaligned_be32(p) << 32 | ++ __get_unaligned_be32(p + 4); ++} ++ ++static inline void __put_unaligned_be16(u16 val, u8 *p) ++{ ++ *p++ = val >> 8; ++ *p++ = val; ++} ++ ++static inline void __put_unaligned_be32(u32 val, u8 *p) ++{ ++ __put_unaligned_be16(val >> 16, p); ++ __put_unaligned_be16(val, p + 2); ++} ++ ++static inline void __put_unaligned_be64(u64 val, u8 *p) ++{ ++ __put_unaligned_be32(val >> 32, p); ++ __put_unaligned_be32(val, p + 4); ++} ++ ++static inline u16 get_unaligned_be16(const void *p) ++{ ++ return __get_unaligned_be16((const u8 *)p); ++} ++ ++static inline u32 get_unaligned_be32(const void *p) ++{ ++ return __get_unaligned_be32((const u8 *)p); ++} ++ ++static inline u64 get_unaligned_be64(const void *p) ++{ ++ return __get_unaligned_be64((const u8 *)p); ++} ++ ++static inline void put_unaligned_be16(u16 val, void *p) ++{ ++ __put_unaligned_be16(val, p); ++} ++ ++static inline void put_unaligned_be32(u32 val, void *p) ++{ ++ __put_unaligned_be32(val, p); ++} ++ ++static inline void put_unaligned_be64(u64 val, void *p) ++{ ++ __put_unaligned_be64(val, p); ++} ++ ++#endif /* _LINUX_UNALIGNED_BE_BYTESHIFT_H */ diff --cc compat/include/linux/unaligned/be_memmove.h index 000000000000,000000000000..c2a76c5c9ed0 new file mode 100644 --- /dev/null +++ b/compat/include/linux/unaligned/be_memmove.h @@@ -1,0 -1,0 +1,36 @@@ ++#ifndef _LINUX_UNALIGNED_BE_MEMMOVE_H ++#define _LINUX_UNALIGNED_BE_MEMMOVE_H ++ ++#include ++ ++static inline u16 get_unaligned_be16(const void *p) ++{ ++ return __get_unaligned_memmove16((const u8 *)p); ++} ++ ++static inline u32 get_unaligned_be32(const void *p) ++{ ++ return __get_unaligned_memmove32((const u8 *)p); ++} ++ ++static inline u64 get_unaligned_be64(const void *p) ++{ ++ return __get_unaligned_memmove64((const u8 *)p); ++} ++ ++static inline void put_unaligned_be16(u16 val, void *p) ++{ ++ __put_unaligned_memmove16(val, p); ++} ++ ++static inline void put_unaligned_be32(u32 val, void *p) ++{ ++ __put_unaligned_memmove32(val, p); ++} ++ ++static inline void put_unaligned_be64(u64 val, void *p) ++{ ++ __put_unaligned_memmove64(val, p); ++} ++ ++#endif /* _LINUX_UNALIGNED_LE_MEMMOVE_H */ diff --cc compat/include/linux/unaligned/be_struct.h index 000000000000,000000000000..132415836c50 new file mode 100644 --- /dev/null +++ b/compat/include/linux/unaligned/be_struct.h @@@ -1,0 -1,0 +1,36 @@@ ++#ifndef _LINUX_UNALIGNED_BE_STRUCT_H ++#define _LINUX_UNALIGNED_BE_STRUCT_H ++ ++#include ++ ++static inline u16 get_unaligned_be16(const void *p) ++{ ++ return __get_unaligned_cpu16((const u8 *)p); ++} ++ ++static inline u32 get_unaligned_be32(const void *p) ++{ ++ return __get_unaligned_cpu32((const u8 *)p); ++} ++ ++static inline u64 get_unaligned_be64(const void *p) ++{ ++ return __get_unaligned_cpu64((const u8 *)p); ++} ++ ++static inline void put_unaligned_be16(u16 val, void *p) ++{ ++ __put_unaligned_cpu16(val, p); ++} ++ ++static inline void put_unaligned_be32(u32 val, void *p) ++{ ++ __put_unaligned_cpu32(val, p); ++} ++ ++static inline void put_unaligned_be64(u64 val, void *p) ++{ ++ __put_unaligned_cpu64(val, p); ++} ++ ++#endif /* _LINUX_UNALIGNED_BE_STRUCT_H */ diff --cc compat/include/linux/unaligned/generic.h index 000000000000,000000000000..02d97ff3df70 new file mode 100644 --- /dev/null +++ b/compat/include/linux/unaligned/generic.h @@@ -1,0 -1,0 +1,68 @@@ ++#ifndef _LINUX_UNALIGNED_GENERIC_H ++#define _LINUX_UNALIGNED_GENERIC_H ++ ++/* ++ * Cause a link-time error if we try an unaligned access other than ++ * 1,2,4 or 8 bytes long ++ */ ++extern void __bad_unaligned_access_size(void); ++ ++#define __get_unaligned_le(ptr) ((__force typeof(*(ptr)))({ \ ++ __builtin_choose_expr(sizeof(*(ptr)) == 1, *(ptr), \ ++ __builtin_choose_expr(sizeof(*(ptr)) == 2, get_unaligned_le16((ptr)), \ ++ __builtin_choose_expr(sizeof(*(ptr)) == 4, get_unaligned_le32((ptr)), \ ++ __builtin_choose_expr(sizeof(*(ptr)) == 8, get_unaligned_le64((ptr)), \ ++ __bad_unaligned_access_size())))); \ ++ })) ++ ++#define __get_unaligned_be(ptr) ((__force typeof(*(ptr)))({ \ ++ __builtin_choose_expr(sizeof(*(ptr)) == 1, *(ptr), \ ++ __builtin_choose_expr(sizeof(*(ptr)) == 2, get_unaligned_be16((ptr)), \ ++ __builtin_choose_expr(sizeof(*(ptr)) == 4, get_unaligned_be32((ptr)), \ ++ __builtin_choose_expr(sizeof(*(ptr)) == 8, get_unaligned_be64((ptr)), \ ++ __bad_unaligned_access_size())))); \ ++ })) ++ ++#define __put_unaligned_le(val, ptr) ({ \ ++ void *__gu_p = (ptr); \ ++ switch (sizeof(*(ptr))) { \ ++ case 1: \ ++ *(u8 *)__gu_p = (__force u8)(val); \ ++ break; \ ++ case 2: \ ++ put_unaligned_le16((__force u16)(val), __gu_p); \ ++ break; \ ++ case 4: \ ++ put_unaligned_le32((__force u32)(val), __gu_p); \ ++ break; \ ++ case 8: \ ++ put_unaligned_le64((__force u64)(val), __gu_p); \ ++ break; \ ++ default: \ ++ __bad_unaligned_access_size(); \ ++ break; \ ++ } \ ++ (void)0; }) ++ ++#define __put_unaligned_be(val, ptr) ({ \ ++ void *__gu_p = (ptr); \ ++ switch (sizeof(*(ptr))) { \ ++ case 1: \ ++ *(u8 *)__gu_p = (__force u8)(val); \ ++ break; \ ++ case 2: \ ++ put_unaligned_be16((__force u16)(val), __gu_p); \ ++ break; \ ++ case 4: \ ++ put_unaligned_be32((__force u32)(val), __gu_p); \ ++ break; \ ++ case 8: \ ++ put_unaligned_be64((__force u64)(val), __gu_p); \ ++ break; \ ++ default: \ ++ __bad_unaligned_access_size(); \ ++ break; \ ++ } \ ++ (void)0; }) ++ ++#endif /* _LINUX_UNALIGNED_GENERIC_H */ diff --cc compat/include/linux/unaligned/le_byteshift.h index 000000000000,000000000000..be376fb79b64 new file mode 100644 --- /dev/null +++ b/compat/include/linux/unaligned/le_byteshift.h @@@ -1,0 -1,0 +1,70 @@@ ++#ifndef _LINUX_UNALIGNED_LE_BYTESHIFT_H ++#define _LINUX_UNALIGNED_LE_BYTESHIFT_H ++ ++#include ++ ++static inline u16 __get_unaligned_le16(const u8 *p) ++{ ++ return p[0] | p[1] << 8; ++} ++ ++static inline u32 __get_unaligned_le32(const u8 *p) ++{ ++ return p[0] | p[1] << 8 | p[2] << 16 | p[3] << 24; ++} ++ ++static inline u64 __get_unaligned_le64(const u8 *p) ++{ ++ return (u64)__get_unaligned_le32(p + 4) << 32 | ++ __get_unaligned_le32(p); ++} ++ ++static inline void __put_unaligned_le16(u16 val, u8 *p) ++{ ++ *p++ = val; ++ *p++ = val >> 8; ++} ++ ++static inline void __put_unaligned_le32(u32 val, u8 *p) ++{ ++ __put_unaligned_le16(val >> 16, p + 2); ++ __put_unaligned_le16(val, p); ++} ++ ++static inline void __put_unaligned_le64(u64 val, u8 *p) ++{ ++ __put_unaligned_le32(val >> 32, p + 4); ++ __put_unaligned_le32(val, p); ++} ++ ++static inline u16 get_unaligned_le16(const void *p) ++{ ++ return __get_unaligned_le16((const u8 *)p); ++} ++ ++static inline u32 get_unaligned_le32(const void *p) ++{ ++ return __get_unaligned_le32((const u8 *)p); ++} ++ ++static inline u64 get_unaligned_le64(const void *p) ++{ ++ return __get_unaligned_le64((const u8 *)p); ++} ++ ++static inline void put_unaligned_le16(u16 val, void *p) ++{ ++ __put_unaligned_le16(val, p); ++} ++ ++static inline void put_unaligned_le32(u32 val, void *p) ++{ ++ __put_unaligned_le32(val, p); ++} ++ ++static inline void put_unaligned_le64(u64 val, void *p) ++{ ++ __put_unaligned_le64(val, p); ++} ++ ++#endif /* _LINUX_UNALIGNED_LE_BYTESHIFT_H */ diff --cc compat/include/linux/unaligned/le_memmove.h index 000000000000,000000000000..269849bee4ec new file mode 100644 --- /dev/null +++ b/compat/include/linux/unaligned/le_memmove.h @@@ -1,0 -1,0 +1,36 @@@ ++#ifndef _LINUX_UNALIGNED_LE_MEMMOVE_H ++#define _LINUX_UNALIGNED_LE_MEMMOVE_H ++ ++#include ++ ++static inline u16 get_unaligned_le16(const void *p) ++{ ++ return __get_unaligned_memmove16((const u8 *)p); ++} ++ ++static inline u32 get_unaligned_le32(const void *p) ++{ ++ return __get_unaligned_memmove32((const u8 *)p); ++} ++ ++static inline u64 get_unaligned_le64(const void *p) ++{ ++ return __get_unaligned_memmove64((const u8 *)p); ++} ++ ++static inline void put_unaligned_le16(u16 val, void *p) ++{ ++ __put_unaligned_memmove16(val, p); ++} ++ ++static inline void put_unaligned_le32(u32 val, void *p) ++{ ++ __put_unaligned_memmove32(val, p); ++} ++ ++static inline void put_unaligned_le64(u64 val, void *p) ++{ ++ __put_unaligned_memmove64(val, p); ++} ++ ++#endif /* _LINUX_UNALIGNED_LE_MEMMOVE_H */ diff --cc compat/include/linux/unaligned/le_struct.h index 000000000000,000000000000..088c4572faa8 new file mode 100644 --- /dev/null +++ b/compat/include/linux/unaligned/le_struct.h @@@ -1,0 -1,0 +1,36 @@@ ++#ifndef _LINUX_UNALIGNED_LE_STRUCT_H ++#define _LINUX_UNALIGNED_LE_STRUCT_H ++ ++#include ++ ++static inline u16 get_unaligned_le16(const void *p) ++{ ++ return __get_unaligned_cpu16((const u8 *)p); ++} ++ ++static inline u32 get_unaligned_le32(const void *p) ++{ ++ return __get_unaligned_cpu32((const u8 *)p); ++} ++ ++static inline u64 get_unaligned_le64(const void *p) ++{ ++ return __get_unaligned_cpu64((const u8 *)p); ++} ++ ++static inline void put_unaligned_le16(u16 val, void *p) ++{ ++ __put_unaligned_cpu16(val, p); ++} ++ ++static inline void put_unaligned_le32(u32 val, void *p) ++{ ++ __put_unaligned_cpu32(val, p); ++} ++ ++static inline void put_unaligned_le64(u64 val, void *p) ++{ ++ __put_unaligned_cpu64(val, p); ++} ++ ++#endif /* _LINUX_UNALIGNED_LE_STRUCT_H */ diff --cc compat/include/linux/unaligned/memmove.h index 000000000000,000000000000..eeb5a779a4fd new file mode 100644 --- /dev/null +++ b/compat/include/linux/unaligned/memmove.h @@@ -1,0 -1,0 +1,45 @@@ ++#ifndef _LINUX_UNALIGNED_MEMMOVE_H ++#define _LINUX_UNALIGNED_MEMMOVE_H ++ ++#include ++#include ++ ++/* Use memmove here, so gcc does not insert a __builtin_memcpy. */ ++ ++static inline u16 __get_unaligned_memmove16(const void *p) ++{ ++ u16 tmp; ++ memmove(&tmp, p, 2); ++ return tmp; ++} ++ ++static inline u32 __get_unaligned_memmove32(const void *p) ++{ ++ u32 tmp; ++ memmove(&tmp, p, 4); ++ return tmp; ++} ++ ++static inline u64 __get_unaligned_memmove64(const void *p) ++{ ++ u64 tmp; ++ memmove(&tmp, p, 8); ++ return tmp; ++} ++ ++static inline void __put_unaligned_memmove16(u16 val, void *p) ++{ ++ memmove(p, &val, 2); ++} ++ ++static inline void __put_unaligned_memmove32(u32 val, void *p) ++{ ++ memmove(p, &val, 4); ++} ++ ++static inline void __put_unaligned_memmove64(u64 val, void *p) ++{ ++ memmove(p, &val, 8); ++} ++ ++#endif /* _LINUX_UNALIGNED_MEMMOVE_H */ diff --cc compat/include/linux/unaligned/packed_struct.h index 000000000000,000000000000..2498bb9fe002 new file mode 100644 --- /dev/null +++ b/compat/include/linux/unaligned/packed_struct.h @@@ -1,0 -1,0 +1,46 @@@ ++#ifndef _LINUX_UNALIGNED_PACKED_STRUCT_H ++#define _LINUX_UNALIGNED_PACKED_STRUCT_H ++ ++#include ++ ++struct __una_u16 { u16 x __attribute__((packed)); }; ++struct __una_u32 { u32 x __attribute__((packed)); }; ++struct __una_u64 { u64 x __attribute__((packed)); }; ++ ++static inline u16 __get_unaligned_cpu16(const void *p) ++{ ++ const struct __una_u16 *ptr = (const struct __una_u16 *)p; ++ return ptr->x; ++} ++ ++static inline u32 __get_unaligned_cpu32(const void *p) ++{ ++ const struct __una_u32 *ptr = (const struct __una_u32 *)p; ++ return ptr->x; ++} ++ ++static inline u64 __get_unaligned_cpu64(const void *p) ++{ ++ const struct __una_u64 *ptr = (const struct __una_u64 *)p; ++ return ptr->x; ++} ++ ++static inline void __put_unaligned_cpu16(u16 val, void *p) ++{ ++ struct __una_u16 *ptr = (struct __una_u16 *)p; ++ ptr->x = val; ++} ++ ++static inline void __put_unaligned_cpu32(u32 val, void *p) ++{ ++ struct __una_u32 *ptr = (struct __una_u32 *)p; ++ ptr->x = val; ++} ++ ++static inline void __put_unaligned_cpu64(u64 val, void *p) ++{ ++ struct __una_u64 *ptr = (struct __una_u64 *)p; ++ ptr->x = val; ++} ++ ++#endif /* _LINUX_UNALIGNED_PACKED_STRUCT_H */ diff --cc compat/include/linux/vga_switcheroo.h index 000000000000,000000000000..4bda17bf88fa new file mode 100644 --- /dev/null +++ b/compat/include/linux/vga_switcheroo.h @@@ -1,0 -1,0 +1,12 @@@ ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34)) ++/* ++ * XXX: The include guard was sent upstream, drop this ++ * once the guard is merged. ++ */ ++#ifndef LINUX_VGA_SWITCHEROO_H /* in case this gets upstream */ ++#include_next ++#ifndef LINUX_VGA_SWITCHEROO_H /* do not redefine once this gets upstream */ ++#define LINUX_VGA_SWITCHEROO_H ++#endif /* case 1 LINUX_VGA_SWITCHEROO_H */ ++#endif /* case 2 LINUX_VGA_SWITCHEROO_H */ ++#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34)) */ diff --cc compat/include/linux/wireless.h index 000000000000,000000000000..4395b28bb86c new file mode 100644 --- /dev/null +++ b/compat/include/linux/wireless.h @@@ -1,0 -1,0 +1,1162 @@@ ++/* ++ * This file define a set of standard wireless extensions ++ * ++ * Version : 22 16.3.07 ++ * ++ * Authors : Jean Tourrilhes - HPL - ++ * Copyright (c) 1997-2007 Jean Tourrilhes, All Rights Reserved. ++ */ ++ ++#ifndef _LINUX_WIRELESS_H ++#define _LINUX_WIRELESS_H ++ ++/************************** DOCUMENTATION **************************/ ++/* ++ * Initial APIs (1996 -> onward) : ++ * ----------------------------- ++ * Basically, the wireless extensions are for now a set of standard ioctl ++ * call + /proc/net/wireless ++ * ++ * The entry /proc/net/wireless give statistics and information on the ++ * driver. ++ * This is better than having each driver having its entry because ++ * its centralised and we may remove the driver module safely. ++ * ++ * Ioctl are used to configure the driver and issue commands. This is ++ * better than command line options of insmod because we may want to ++ * change dynamically (while the driver is running) some parameters. ++ * ++ * The ioctl mechanimsm are copied from standard devices ioctl. ++ * We have the list of command plus a structure descibing the ++ * data exchanged... ++ * Note that to add these ioctl, I was obliged to modify : ++ * # net/core/dev.c (two place + add include) ++ * # net/ipv4/af_inet.c (one place + add include) ++ * ++ * /proc/net/wireless is a copy of /proc/net/dev. ++ * We have a structure for data passed from the driver to /proc/net/wireless ++ * Too add this, I've modified : ++ * # net/core/dev.c (two other places) ++ * # include/linux/netdevice.h (one place) ++ * # include/linux/proc_fs.h (one place) ++ * ++ * New driver API (2002 -> onward) : ++ * ------------------------------- ++ * This file is only concerned with the user space API and common definitions. ++ * The new driver API is defined and documented in : ++ * # include/net/iw_handler.h ++ * ++ * Note as well that /proc/net/wireless implementation has now moved in : ++ * # net/core/wireless.c ++ * ++ * Wireless Events (2002 -> onward) : ++ * -------------------------------- ++ * Events are defined at the end of this file, and implemented in : ++ * # net/core/wireless.c ++ * ++ * Other comments : ++ * -------------- ++ * Do not add here things that are redundant with other mechanisms ++ * (drivers init, ifconfig, /proc/net/dev, ...) and with are not ++ * wireless specific. ++ * ++ * These wireless extensions are not magic : each driver has to provide ++ * support for them... ++ * ++ * IMPORTANT NOTE : As everything in the kernel, this is very much a ++ * work in progress. Contact me if you have ideas of improvements... ++ */ ++ ++/***************************** INCLUDES *****************************/ ++ ++#include /* for __u* and __s* typedefs */ ++#include /* for "struct sockaddr" et al */ ++#include /* for IFNAMSIZ and co... */ ++ ++/***************************** VERSION *****************************/ ++/* ++ * This constant is used to know the availability of the wireless ++ * extensions and to know which version of wireless extensions it is ++ * (there is some stuff that will be added in the future...) ++ * I just plan to increment with each new version. ++ */ ++#define WIRELESS_EXT 22 ++ ++/* ++ * Changes : ++ * ++ * V2 to V3 ++ * -------- ++ * Alan Cox start some incompatibles changes. I've integrated a bit more. ++ * - Encryption renamed to Encode to avoid US regulation problems ++ * - Frequency changed from float to struct to avoid problems on old 386 ++ * ++ * V3 to V4 ++ * -------- ++ * - Add sensitivity ++ * ++ * V4 to V5 ++ * -------- ++ * - Missing encoding definitions in range ++ * - Access points stuff ++ * ++ * V5 to V6 ++ * -------- ++ * - 802.11 support (ESSID ioctls) ++ * ++ * V6 to V7 ++ * -------- ++ * - define IW_ESSID_MAX_SIZE and IW_MAX_AP ++ * ++ * V7 to V8 ++ * -------- ++ * - Changed my e-mail address ++ * - More 802.11 support (nickname, rate, rts, frag) ++ * - List index in frequencies ++ * ++ * V8 to V9 ++ * -------- ++ * - Support for 'mode of operation' (ad-hoc, managed...) ++ * - Support for unicast and multicast power saving ++ * - Change encoding to support larger tokens (>64 bits) ++ * - Updated iw_params (disable, flags) and use it for NWID ++ * - Extracted iw_point from iwreq for clarity ++ * ++ * V9 to V10 ++ * --------- ++ * - Add PM capability to range structure ++ * - Add PM modifier : MAX/MIN/RELATIVE ++ * - Add encoding option : IW_ENCODE_NOKEY ++ * - Add TxPower ioctls (work like TxRate) ++ * ++ * V10 to V11 ++ * ---------- ++ * - Add WE version in range (help backward/forward compatibility) ++ * - Add retry ioctls (work like PM) ++ * ++ * V11 to V12 ++ * ---------- ++ * - Add SIOCSIWSTATS to get /proc/net/wireless programatically ++ * - Add DEV PRIVATE IOCTL to avoid collisions in SIOCDEVPRIVATE space ++ * - Add new statistics (frag, retry, beacon) ++ * - Add average quality (for user space calibration) ++ * ++ * V12 to V13 ++ * ---------- ++ * - Document creation of new driver API. ++ * - Extract union iwreq_data from struct iwreq (for new driver API). ++ * - Rename SIOCSIWNAME as SIOCSIWCOMMIT ++ * ++ * V13 to V14 ++ * ---------- ++ * - Wireless Events support : define struct iw_event ++ * - Define additional specific event numbers ++ * - Add "addr" and "param" fields in union iwreq_data ++ * - AP scanning stuff (SIOCSIWSCAN and friends) ++ * ++ * V14 to V15 ++ * ---------- ++ * - Add IW_PRIV_TYPE_ADDR for struct sockaddr private arg ++ * - Make struct iw_freq signed (both m & e), add explicit padding ++ * - Add IWEVCUSTOM for driver specific event/scanning token ++ * - Add IW_MAX_GET_SPY for driver returning a lot of addresses ++ * - Add IW_TXPOW_RANGE for range of Tx Powers ++ * - Add IWEVREGISTERED & IWEVEXPIRED events for Access Points ++ * - Add IW_MODE_MONITOR for passive monitor ++ * ++ * V15 to V16 ++ * ---------- ++ * - Increase the number of bitrates in iw_range to 32 (for 802.11g) ++ * - Increase the number of frequencies in iw_range to 32 (for 802.11b+a) ++ * - Reshuffle struct iw_range for increases, add filler ++ * - Increase IW_MAX_AP to 64 for driver returning a lot of addresses ++ * - Remove IW_MAX_GET_SPY because conflict with enhanced spy support ++ * - Add SIOCSIWTHRSPY/SIOCGIWTHRSPY and "struct iw_thrspy" ++ * - Add IW_ENCODE_TEMP and iw_range->encoding_login_index ++ * ++ * V16 to V17 ++ * ---------- ++ * - Add flags to frequency -> auto/fixed ++ * - Document (struct iw_quality *)->updated, add new flags (INVALID) ++ * - Wireless Event capability in struct iw_range ++ * - Add support for relative TxPower (yick !) ++ * ++ * V17 to V18 (From Jouni Malinen ) ++ * ---------- ++ * - Add support for WPA/WPA2 ++ * - Add extended encoding configuration (SIOCSIWENCODEEXT and ++ * SIOCGIWENCODEEXT) ++ * - Add SIOCSIWGENIE/SIOCGIWGENIE ++ * - Add SIOCSIWMLME ++ * - Add SIOCSIWPMKSA ++ * - Add struct iw_range bit field for supported encoding capabilities ++ * - Add optional scan request parameters for SIOCSIWSCAN ++ * - Add SIOCSIWAUTH/SIOCGIWAUTH for setting authentication and WPA ++ * related parameters (extensible up to 4096 parameter values) ++ * - Add wireless events: IWEVGENIE, IWEVMICHAELMICFAILURE, ++ * IWEVASSOCREQIE, IWEVASSOCRESPIE, IWEVPMKIDCAND ++ * ++ * V18 to V19 ++ * ---------- ++ * - Remove (struct iw_point *)->pointer from events and streams ++ * - Remove header includes to help user space ++ * - Increase IW_ENCODING_TOKEN_MAX from 32 to 64 ++ * - Add IW_QUAL_ALL_UPDATED and IW_QUAL_ALL_INVALID macros ++ * - Add explicit flag to tell stats are in dBm : IW_QUAL_DBM ++ * - Add IW_IOCTL_IDX() and IW_EVENT_IDX() macros ++ * ++ * V19 to V20 ++ * ---------- ++ * - RtNetlink requests support (SET/GET) ++ * ++ * V20 to V21 ++ * ---------- ++ * - Remove (struct net_device *)->get_wireless_stats() ++ * - Change length in ESSID and NICK to strlen() instead of strlen()+1 ++ * - Add IW_RETRY_SHORT/IW_RETRY_LONG retry modifiers ++ * - Power/Retry relative values no longer * 100000 ++ * - Add explicit flag to tell stats are in 802.11k RCPI : IW_QUAL_RCPI ++ * ++ * V21 to V22 ++ * ---------- ++ * - Prevent leaking of kernel space in stream on 64 bits. ++ */ ++ ++/**************************** CONSTANTS ****************************/ ++ ++/* -------------------------- IOCTL LIST -------------------------- */ ++ ++/* Wireless Identification */ ++#define SIOCSIWCOMMIT 0x8B00 /* Commit pending changes to driver */ ++#define SIOCGIWNAME 0x8B01 /* get name == wireless protocol */ ++/* SIOCGIWNAME is used to verify the presence of Wireless Extensions. ++ * Common values : "IEEE 802.11-DS", "IEEE 802.11-FH", "IEEE 802.11b"... ++ * Don't put the name of your driver there, it's useless. */ ++ ++/* Basic operations */ ++#define SIOCSIWNWID 0x8B02 /* set network id (pre-802.11) */ ++#define SIOCGIWNWID 0x8B03 /* get network id (the cell) */ ++#define SIOCSIWFREQ 0x8B04 /* set channel/frequency (Hz) */ ++#define SIOCGIWFREQ 0x8B05 /* get channel/frequency (Hz) */ ++#define SIOCSIWMODE 0x8B06 /* set operation mode */ ++#define SIOCGIWMODE 0x8B07 /* get operation mode */ ++#define SIOCSIWSENS 0x8B08 /* set sensitivity (dBm) */ ++#define SIOCGIWSENS 0x8B09 /* get sensitivity (dBm) */ ++ ++/* Informative stuff */ ++#define SIOCSIWRANGE 0x8B0A /* Unused */ ++#define SIOCGIWRANGE 0x8B0B /* Get range of parameters */ ++#define SIOCSIWPRIV 0x8B0C /* Unused */ ++#define SIOCGIWPRIV 0x8B0D /* get private ioctl interface info */ ++#define SIOCSIWSTATS 0x8B0E /* Unused */ ++#define SIOCGIWSTATS 0x8B0F /* Get /proc/net/wireless stats */ ++/* SIOCGIWSTATS is strictly used between user space and the kernel, and ++ * is never passed to the driver (i.e. the driver will never see it). */ ++ ++/* Spy support (statistics per MAC address - used for Mobile IP support) */ ++#define SIOCSIWSPY 0x8B10 /* set spy addresses */ ++#define SIOCGIWSPY 0x8B11 /* get spy info (quality of link) */ ++#define SIOCSIWTHRSPY 0x8B12 /* set spy threshold (spy event) */ ++#define SIOCGIWTHRSPY 0x8B13 /* get spy threshold */ ++ ++/* Access Point manipulation */ ++#define SIOCSIWAP 0x8B14 /* set access point MAC addresses */ ++#define SIOCGIWAP 0x8B15 /* get access point MAC addresses */ ++#define SIOCGIWAPLIST 0x8B17 /* Deprecated in favor of scanning */ ++#define SIOCSIWSCAN 0x8B18 /* trigger scanning (list cells) */ ++#define SIOCGIWSCAN 0x8B19 /* get scanning results */ ++ ++/* 802.11 specific support */ ++#define SIOCSIWESSID 0x8B1A /* set ESSID (network name) */ ++#define SIOCGIWESSID 0x8B1B /* get ESSID */ ++#define SIOCSIWNICKN 0x8B1C /* set node name/nickname */ ++#define SIOCGIWNICKN 0x8B1D /* get node name/nickname */ ++/* As the ESSID and NICKN are strings up to 32 bytes long, it doesn't fit ++ * within the 'iwreq' structure, so we need to use the 'data' member to ++ * point to a string in user space, like it is done for RANGE... */ ++ ++/* Other parameters useful in 802.11 and some other devices */ ++#define SIOCSIWRATE 0x8B20 /* set default bit rate (bps) */ ++#define SIOCGIWRATE 0x8B21 /* get default bit rate (bps) */ ++#define SIOCSIWRTS 0x8B22 /* set RTS/CTS threshold (bytes) */ ++#define SIOCGIWRTS 0x8B23 /* get RTS/CTS threshold (bytes) */ ++#define SIOCSIWFRAG 0x8B24 /* set fragmentation thr (bytes) */ ++#define SIOCGIWFRAG 0x8B25 /* get fragmentation thr (bytes) */ ++#define SIOCSIWTXPOW 0x8B26 /* set transmit power (dBm) */ ++#define SIOCGIWTXPOW 0x8B27 /* get transmit power (dBm) */ ++#define SIOCSIWRETRY 0x8B28 /* set retry limits and lifetime */ ++#define SIOCGIWRETRY 0x8B29 /* get retry limits and lifetime */ ++ ++/* Encoding stuff (scrambling, hardware security, WEP...) */ ++#define SIOCSIWENCODE 0x8B2A /* set encoding token & mode */ ++#define SIOCGIWENCODE 0x8B2B /* get encoding token & mode */ ++/* Power saving stuff (power management, unicast and multicast) */ ++#define SIOCSIWPOWER 0x8B2C /* set Power Management settings */ ++#define SIOCGIWPOWER 0x8B2D /* get Power Management settings */ ++ ++/* WPA : Generic IEEE 802.11 informatiom element (e.g., for WPA/RSN/WMM). ++ * This ioctl uses struct iw_point and data buffer that includes IE id and len ++ * fields. More than one IE may be included in the request. Setting the generic ++ * IE to empty buffer (len=0) removes the generic IE from the driver. Drivers ++ * are allowed to generate their own WPA/RSN IEs, but in these cases, drivers ++ * are required to report the used IE as a wireless event, e.g., when ++ * associating with an AP. */ ++#define SIOCSIWGENIE 0x8B30 /* set generic IE */ ++#define SIOCGIWGENIE 0x8B31 /* get generic IE */ ++ ++/* WPA : IEEE 802.11 MLME requests */ ++#define SIOCSIWMLME 0x8B16 /* request MLME operation; uses ++ * struct iw_mlme */ ++/* WPA : Authentication mode parameters */ ++#define SIOCSIWAUTH 0x8B32 /* set authentication mode params */ ++#define SIOCGIWAUTH 0x8B33 /* get authentication mode params */ ++ ++/* WPA : Extended version of encoding configuration */ ++#define SIOCSIWENCODEEXT 0x8B34 /* set encoding token & mode */ ++#define SIOCGIWENCODEEXT 0x8B35 /* get encoding token & mode */ ++ ++/* WPA2 : PMKSA cache management */ ++#define SIOCSIWPMKSA 0x8B36 /* PMKSA cache operation */ ++ ++/* -------------------- DEV PRIVATE IOCTL LIST -------------------- */ ++ ++/* These 32 ioctl are wireless device private, for 16 commands. ++ * Each driver is free to use them for whatever purpose it chooses, ++ * however the driver *must* export the description of those ioctls ++ * with SIOCGIWPRIV and *must* use arguments as defined below. ++ * If you don't follow those rules, DaveM is going to hate you (reason : ++ * it make mixed 32/64bit operation impossible). ++ */ ++#define SIOCIWFIRSTPRIV 0x8BE0 ++#define SIOCIWLASTPRIV 0x8BFF ++/* Previously, we were using SIOCDEVPRIVATE, but we now have our ++ * separate range because of collisions with other tools such as ++ * 'mii-tool'. ++ * We now have 32 commands, so a bit more space ;-). ++ * Also, all 'even' commands are only usable by root and don't return the ++ * content of ifr/iwr to user (but you are not obliged to use the set/get ++ * convention, just use every other two command). More details in iwpriv.c. ++ * And I repeat : you are not forced to use them with iwpriv, but you ++ * must be compliant with it. ++ */ ++ ++/* ------------------------- IOCTL STUFF ------------------------- */ ++ ++/* The first and the last (range) */ ++#define SIOCIWFIRST 0x8B00 ++#define SIOCIWLAST SIOCIWLASTPRIV /* 0x8BFF */ ++#define IW_IOCTL_IDX(cmd) ((cmd) - SIOCIWFIRST) ++#define IW_HANDLER(id, func) \ ++ [IW_IOCTL_IDX(id)] = func ++ ++/* Odd : get (world access), even : set (root access) */ ++#define IW_IS_SET(cmd) (!((cmd) & 0x1)) ++#define IW_IS_GET(cmd) ((cmd) & 0x1) ++ ++/* ----------------------- WIRELESS EVENTS ----------------------- */ ++/* Those are *NOT* ioctls, do not issue request on them !!! */ ++/* Most events use the same identifier as ioctl requests */ ++ ++#define IWEVTXDROP 0x8C00 /* Packet dropped to excessive retry */ ++#define IWEVQUAL 0x8C01 /* Quality part of statistics (scan) */ ++#define IWEVCUSTOM 0x8C02 /* Driver specific ascii string */ ++#define IWEVREGISTERED 0x8C03 /* Discovered a new node (AP mode) */ ++#define IWEVEXPIRED 0x8C04 /* Expired a node (AP mode) */ ++#define IWEVGENIE 0x8C05 /* Generic IE (WPA, RSN, WMM, ..) ++ * (scan results); This includes id and ++ * length fields. One IWEVGENIE may ++ * contain more than one IE. Scan ++ * results may contain one or more ++ * IWEVGENIE events. */ ++#define IWEVMICHAELMICFAILURE 0x8C06 /* Michael MIC failure ++ * (struct iw_michaelmicfailure) ++ */ ++#define IWEVASSOCREQIE 0x8C07 /* IEs used in (Re)Association Request. ++ * The data includes id and length ++ * fields and may contain more than one ++ * IE. This event is required in ++ * Managed mode if the driver ++ * generates its own WPA/RSN IE. This ++ * should be sent just before ++ * IWEVREGISTERED event for the ++ * association. */ ++#define IWEVASSOCRESPIE 0x8C08 /* IEs used in (Re)Association ++ * Response. The data includes id and ++ * length fields and may contain more ++ * than one IE. This may be sent ++ * between IWEVASSOCREQIE and ++ * IWEVREGISTERED events for the ++ * association. */ ++#define IWEVPMKIDCAND 0x8C09 /* PMKID candidate for RSN ++ * pre-authentication ++ * (struct iw_pmkid_cand) */ ++ ++#define IWEVFIRST 0x8C00 ++#define IW_EVENT_IDX(cmd) ((cmd) - IWEVFIRST) ++ ++/* ------------------------- PRIVATE INFO ------------------------- */ ++/* ++ * The following is used with SIOCGIWPRIV. It allow a driver to define ++ * the interface (name, type of data) for its private ioctl. ++ * Privates ioctl are SIOCIWFIRSTPRIV -> SIOCIWLASTPRIV ++ */ ++ ++#define IW_PRIV_TYPE_MASK 0x7000 /* Type of arguments */ ++#define IW_PRIV_TYPE_NONE 0x0000 ++#define IW_PRIV_TYPE_BYTE 0x1000 /* Char as number */ ++#define IW_PRIV_TYPE_CHAR 0x2000 /* Char as character */ ++#define IW_PRIV_TYPE_INT 0x4000 /* 32 bits int */ ++#define IW_PRIV_TYPE_FLOAT 0x5000 /* struct iw_freq */ ++#define IW_PRIV_TYPE_ADDR 0x6000 /* struct sockaddr */ ++ ++#define IW_PRIV_SIZE_FIXED 0x0800 /* Variable or fixed number of args */ ++ ++#define IW_PRIV_SIZE_MASK 0x07FF /* Max number of those args */ ++ ++/* ++ * Note : if the number of args is fixed and the size < 16 octets, ++ * instead of passing a pointer we will put args in the iwreq struct... ++ */ ++ ++/* ----------------------- OTHER CONSTANTS ----------------------- */ ++ ++/* Maximum frequencies in the range struct */ ++#define IW_MAX_FREQUENCIES 32 ++/* Note : if you have something like 80 frequencies, ++ * don't increase this constant and don't fill the frequency list. ++ * The user will be able to set by channel anyway... */ ++ ++/* Maximum bit rates in the range struct */ ++#define IW_MAX_BITRATES 32 ++ ++/* Maximum tx powers in the range struct */ ++#define IW_MAX_TXPOWER 8 ++/* Note : if you more than 8 TXPowers, just set the max and min or ++ * a few of them in the struct iw_range. */ ++ ++/* Maximum of address that you may set with SPY */ ++#define IW_MAX_SPY 8 ++ ++/* Maximum of address that you may get in the ++ list of access points in range */ ++#define IW_MAX_AP 64 ++ ++/* Maximum size of the ESSID and NICKN strings */ ++#define IW_ESSID_MAX_SIZE 32 ++ ++/* Modes of operation */ ++#define IW_MODE_AUTO 0 /* Let the driver decides */ ++#define IW_MODE_ADHOC 1 /* Single cell network */ ++#define IW_MODE_INFRA 2 /* Multi cell network, roaming, ... */ ++#define IW_MODE_MASTER 3 /* Synchronisation master or Access Point */ ++#define IW_MODE_REPEAT 4 /* Wireless Repeater (forwarder) */ ++#define IW_MODE_SECOND 5 /* Secondary master/repeater (backup) */ ++#define IW_MODE_MONITOR 6 /* Passive monitor (listen only) */ ++#define IW_MODE_MESH 7 /* Mesh (IEEE 802.11s) network */ ++ ++/* Statistics flags (bitmask in updated) */ ++#define IW_QUAL_QUAL_UPDATED 0x01 /* Value was updated since last read */ ++#define IW_QUAL_LEVEL_UPDATED 0x02 ++#define IW_QUAL_NOISE_UPDATED 0x04 ++#define IW_QUAL_ALL_UPDATED 0x07 ++#define IW_QUAL_DBM 0x08 /* Level + Noise are dBm */ ++#define IW_QUAL_QUAL_INVALID 0x10 /* Driver doesn't provide value */ ++#define IW_QUAL_LEVEL_INVALID 0x20 ++#define IW_QUAL_NOISE_INVALID 0x40 ++#define IW_QUAL_RCPI 0x80 /* Level + Noise are 802.11k RCPI */ ++#define IW_QUAL_ALL_INVALID 0x70 ++ ++/* Frequency flags */ ++#define IW_FREQ_AUTO 0x00 /* Let the driver decides */ ++#define IW_FREQ_FIXED 0x01 /* Force a specific value */ ++ ++/* Maximum number of size of encoding token available ++ * they are listed in the range structure */ ++#define IW_MAX_ENCODING_SIZES 8 ++ ++/* Maximum size of the encoding token in bytes */ ++#define IW_ENCODING_TOKEN_MAX 64 /* 512 bits (for now) */ ++ ++/* Flags for encoding (along with the token) */ ++#define IW_ENCODE_INDEX 0x00FF /* Token index (if needed) */ ++#define IW_ENCODE_FLAGS 0xFF00 /* Flags defined below */ ++#define IW_ENCODE_MODE 0xF000 /* Modes defined below */ ++#define IW_ENCODE_DISABLED 0x8000 /* Encoding disabled */ ++#define IW_ENCODE_ENABLED 0x0000 /* Encoding enabled */ ++#define IW_ENCODE_RESTRICTED 0x4000 /* Refuse non-encoded packets */ ++#define IW_ENCODE_OPEN 0x2000 /* Accept non-encoded packets */ ++#define IW_ENCODE_NOKEY 0x0800 /* Key is write only, so not present */ ++#define IW_ENCODE_TEMP 0x0400 /* Temporary key */ ++ ++/* Power management flags available (along with the value, if any) */ ++#define IW_POWER_ON 0x0000 /* No details... */ ++#define IW_POWER_TYPE 0xF000 /* Type of parameter */ ++#define IW_POWER_PERIOD 0x1000 /* Value is a period/duration of */ ++#define IW_POWER_TIMEOUT 0x2000 /* Value is a timeout (to go asleep) */ ++#define IW_POWER_MODE 0x0F00 /* Power Management mode */ ++#define IW_POWER_UNICAST_R 0x0100 /* Receive only unicast messages */ ++#define IW_POWER_MULTICAST_R 0x0200 /* Receive only multicast messages */ ++#define IW_POWER_ALL_R 0x0300 /* Receive all messages though PM */ ++#define IW_POWER_FORCE_S 0x0400 /* Force PM procedure for sending unicast */ ++#define IW_POWER_REPEATER 0x0800 /* Repeat broadcast messages in PM period */ ++#define IW_POWER_MODIFIER 0x000F /* Modify a parameter */ ++#define IW_POWER_MIN 0x0001 /* Value is a minimum */ ++#define IW_POWER_MAX 0x0002 /* Value is a maximum */ ++#define IW_POWER_RELATIVE 0x0004 /* Value is not in seconds/ms/us */ ++ ++/* Transmit Power flags available */ ++#define IW_TXPOW_TYPE 0x00FF /* Type of value */ ++#define IW_TXPOW_DBM 0x0000 /* Value is in dBm */ ++#define IW_TXPOW_MWATT 0x0001 /* Value is in mW */ ++#define IW_TXPOW_RELATIVE 0x0002 /* Value is in arbitrary units */ ++#define IW_TXPOW_RANGE 0x1000 /* Range of value between min/max */ ++ ++/* Retry limits and lifetime flags available */ ++#define IW_RETRY_ON 0x0000 /* No details... */ ++#define IW_RETRY_TYPE 0xF000 /* Type of parameter */ ++#define IW_RETRY_LIMIT 0x1000 /* Maximum number of retries*/ ++#define IW_RETRY_LIFETIME 0x2000 /* Maximum duration of retries in us */ ++#define IW_RETRY_MODIFIER 0x00FF /* Modify a parameter */ ++#define IW_RETRY_MIN 0x0001 /* Value is a minimum */ ++#define IW_RETRY_MAX 0x0002 /* Value is a maximum */ ++#define IW_RETRY_RELATIVE 0x0004 /* Value is not in seconds/ms/us */ ++#define IW_RETRY_SHORT 0x0010 /* Value is for short packets */ ++#define IW_RETRY_LONG 0x0020 /* Value is for long packets */ ++ ++/* Scanning request flags */ ++#define IW_SCAN_DEFAULT 0x0000 /* Default scan of the driver */ ++#define IW_SCAN_ALL_ESSID 0x0001 /* Scan all ESSIDs */ ++#define IW_SCAN_THIS_ESSID 0x0002 /* Scan only this ESSID */ ++#define IW_SCAN_ALL_FREQ 0x0004 /* Scan all Frequencies */ ++#define IW_SCAN_THIS_FREQ 0x0008 /* Scan only this Frequency */ ++#define IW_SCAN_ALL_MODE 0x0010 /* Scan all Modes */ ++#define IW_SCAN_THIS_MODE 0x0020 /* Scan only this Mode */ ++#define IW_SCAN_ALL_RATE 0x0040 /* Scan all Bit-Rates */ ++#define IW_SCAN_THIS_RATE 0x0080 /* Scan only this Bit-Rate */ ++/* struct iw_scan_req scan_type */ ++#define IW_SCAN_TYPE_ACTIVE 0 ++#define IW_SCAN_TYPE_PASSIVE 1 ++/* Maximum size of returned data */ ++#define IW_SCAN_MAX_DATA 4096 /* In bytes */ ++ ++/* Scan capability flags - in (struct iw_range *)->scan_capa */ ++#define IW_SCAN_CAPA_NONE 0x00 ++#define IW_SCAN_CAPA_ESSID 0x01 ++#define IW_SCAN_CAPA_BSSID 0x02 ++#define IW_SCAN_CAPA_CHANNEL 0x04 ++#define IW_SCAN_CAPA_MODE 0x08 ++#define IW_SCAN_CAPA_RATE 0x10 ++#define IW_SCAN_CAPA_TYPE 0x20 ++#define IW_SCAN_CAPA_TIME 0x40 ++ ++/* Max number of char in custom event - use multiple of them if needed */ ++#define IW_CUSTOM_MAX 256 /* In bytes */ ++ ++/* Generic information element */ ++#define IW_GENERIC_IE_MAX 1024 ++ ++/* MLME requests (SIOCSIWMLME / struct iw_mlme) */ ++#define IW_MLME_DEAUTH 0 ++#define IW_MLME_DISASSOC 1 ++#define IW_MLME_AUTH 2 ++#define IW_MLME_ASSOC 3 ++ ++/* SIOCSIWAUTH/SIOCGIWAUTH struct iw_param flags */ ++#define IW_AUTH_INDEX 0x0FFF ++#define IW_AUTH_FLAGS 0xF000 ++/* SIOCSIWAUTH/SIOCGIWAUTH parameters (0 .. 4095) ++ * (IW_AUTH_INDEX mask in struct iw_param flags; this is the index of the ++ * parameter that is being set/get to; value will be read/written to ++ * struct iw_param value field) */ ++#define IW_AUTH_WPA_VERSION 0 ++#define IW_AUTH_CIPHER_PAIRWISE 1 ++#define IW_AUTH_CIPHER_GROUP 2 ++#define IW_AUTH_KEY_MGMT 3 ++#define IW_AUTH_TKIP_COUNTERMEASURES 4 ++#define IW_AUTH_DROP_UNENCRYPTED 5 ++#define IW_AUTH_80211_AUTH_ALG 6 ++#define IW_AUTH_WPA_ENABLED 7 ++#define IW_AUTH_RX_UNENCRYPTED_EAPOL 8 ++#define IW_AUTH_ROAMING_CONTROL 9 ++#define IW_AUTH_PRIVACY_INVOKED 10 ++#define IW_AUTH_CIPHER_GROUP_MGMT 11 ++#define IW_AUTH_MFP 12 ++ ++/* IW_AUTH_WPA_VERSION values (bit field) */ ++#define IW_AUTH_WPA_VERSION_DISABLED 0x00000001 ++#define IW_AUTH_WPA_VERSION_WPA 0x00000002 ++#define IW_AUTH_WPA_VERSION_WPA2 0x00000004 ++ ++/* IW_AUTH_PAIRWISE_CIPHER, IW_AUTH_GROUP_CIPHER, and IW_AUTH_CIPHER_GROUP_MGMT ++ * values (bit field) */ ++#define IW_AUTH_CIPHER_NONE 0x00000001 ++#define IW_AUTH_CIPHER_WEP40 0x00000002 ++#define IW_AUTH_CIPHER_TKIP 0x00000004 ++#define IW_AUTH_CIPHER_CCMP 0x00000008 ++#define IW_AUTH_CIPHER_WEP104 0x00000010 ++#define IW_AUTH_CIPHER_AES_CMAC 0x00000020 ++ ++/* IW_AUTH_KEY_MGMT values (bit field) */ ++#define IW_AUTH_KEY_MGMT_802_1X 1 ++#define IW_AUTH_KEY_MGMT_PSK 2 ++ ++/* IW_AUTH_80211_AUTH_ALG values (bit field) */ ++#define IW_AUTH_ALG_OPEN_SYSTEM 0x00000001 ++#define IW_AUTH_ALG_SHARED_KEY 0x00000002 ++#define IW_AUTH_ALG_LEAP 0x00000004 ++ ++/* IW_AUTH_ROAMING_CONTROL values */ ++#define IW_AUTH_ROAMING_ENABLE 0 /* driver/firmware based roaming */ ++#define IW_AUTH_ROAMING_DISABLE 1 /* user space program used for roaming ++ * control */ ++ ++/* IW_AUTH_MFP (management frame protection) values */ ++#define IW_AUTH_MFP_DISABLED 0 /* MFP disabled */ ++#define IW_AUTH_MFP_OPTIONAL 1 /* MFP optional */ ++#define IW_AUTH_MFP_REQUIRED 2 /* MFP required */ ++ ++/* SIOCSIWENCODEEXT definitions */ ++#define IW_ENCODE_SEQ_MAX_SIZE 8 ++/* struct iw_encode_ext ->alg */ ++#define IW_ENCODE_ALG_NONE 0 ++#define IW_ENCODE_ALG_WEP 1 ++#define IW_ENCODE_ALG_TKIP 2 ++#define IW_ENCODE_ALG_CCMP 3 ++#define IW_ENCODE_ALG_PMK 4 ++#define IW_ENCODE_ALG_AES_CMAC 5 ++/* struct iw_encode_ext ->ext_flags */ ++#define IW_ENCODE_EXT_TX_SEQ_VALID 0x00000001 ++#define IW_ENCODE_EXT_RX_SEQ_VALID 0x00000002 ++#define IW_ENCODE_EXT_GROUP_KEY 0x00000004 ++#define IW_ENCODE_EXT_SET_TX_KEY 0x00000008 ++ ++/* IWEVMICHAELMICFAILURE : struct iw_michaelmicfailure ->flags */ ++#define IW_MICFAILURE_KEY_ID 0x00000003 /* Key ID 0..3 */ ++#define IW_MICFAILURE_GROUP 0x00000004 ++#define IW_MICFAILURE_PAIRWISE 0x00000008 ++#define IW_MICFAILURE_STAKEY 0x00000010 ++#define IW_MICFAILURE_COUNT 0x00000060 /* 1 or 2 (0 = count not supported) ++ */ ++ ++/* Bit field values for enc_capa in struct iw_range */ ++#define IW_ENC_CAPA_WPA 0x00000001 ++#define IW_ENC_CAPA_WPA2 0x00000002 ++#define IW_ENC_CAPA_CIPHER_TKIP 0x00000004 ++#define IW_ENC_CAPA_CIPHER_CCMP 0x00000008 ++#define IW_ENC_CAPA_4WAY_HANDSHAKE 0x00000010 ++ ++/* Event capability macros - in (struct iw_range *)->event_capa ++ * Because we have more than 32 possible events, we use an array of ++ * 32 bit bitmasks. Note : 32 bits = 0x20 = 2^5. */ ++#define IW_EVENT_CAPA_BASE(cmd) ((cmd >= SIOCIWFIRSTPRIV) ? \ ++ (cmd - SIOCIWFIRSTPRIV + 0x60) : \ ++ (cmd - SIOCIWFIRST)) ++#define IW_EVENT_CAPA_INDEX(cmd) (IW_EVENT_CAPA_BASE(cmd) >> 5) ++#define IW_EVENT_CAPA_MASK(cmd) (1 << (IW_EVENT_CAPA_BASE(cmd) & 0x1F)) ++/* Event capability constants - event autogenerated by the kernel ++ * This list is valid for most 802.11 devices, customise as needed... */ ++#define IW_EVENT_CAPA_K_0 (IW_EVENT_CAPA_MASK(0x8B04) | \ ++ IW_EVENT_CAPA_MASK(0x8B06) | \ ++ IW_EVENT_CAPA_MASK(0x8B1A)) ++#define IW_EVENT_CAPA_K_1 (IW_EVENT_CAPA_MASK(0x8B2A)) ++/* "Easy" macro to set events in iw_range (less efficient) */ ++#define IW_EVENT_CAPA_SET(event_capa, cmd) (event_capa[IW_EVENT_CAPA_INDEX(cmd)] |= IW_EVENT_CAPA_MASK(cmd)) ++#define IW_EVENT_CAPA_SET_KERNEL(event_capa) {event_capa[0] |= IW_EVENT_CAPA_K_0; event_capa[1] |= IW_EVENT_CAPA_K_1; } ++ ++ ++/****************************** TYPES ******************************/ ++ ++/* --------------------------- SUBTYPES --------------------------- */ ++/* ++ * Generic format for most parameters that fit in an int ++ */ ++struct iw_param ++{ ++ __s32 value; /* The value of the parameter itself */ ++ __u8 fixed; /* Hardware should not use auto select */ ++ __u8 disabled; /* Disable the feature */ ++ __u16 flags; /* Various specifc flags (if any) */ ++}; ++ ++/* ++ * For all data larger than 16 octets, we need to use a ++ * pointer to memory allocated in user space. ++ */ ++struct iw_point ++{ ++ void __user *pointer; /* Pointer to the data (in user space) */ ++ __u16 length; /* number of fields or size in bytes */ ++ __u16 flags; /* Optional params */ ++}; ++ ++#ifdef __KERNEL__ ++#ifdef CONFIG_COMPAT ++ ++#include ++ ++struct compat_iw_point { ++ compat_caddr_t pointer; ++ __u16 length; ++ __u16 flags; ++}; ++#endif ++#endif ++ ++/* ++ * A frequency ++ * For numbers lower than 10^9, we encode the number in 'm' and ++ * set 'e' to 0 ++ * For number greater than 10^9, we divide it by the lowest power ++ * of 10 to get 'm' lower than 10^9, with 'm'= f / (10^'e')... ++ * The power of 10 is in 'e', the result of the division is in 'm'. ++ */ ++struct iw_freq ++{ ++ __s32 m; /* Mantissa */ ++ __s16 e; /* Exponent */ ++ __u8 i; /* List index (when in range struct) */ ++ __u8 flags; /* Flags (fixed/auto) */ ++}; ++ ++/* ++ * Quality of the link ++ */ ++struct iw_quality ++{ ++ __u8 qual; /* link quality (%retries, SNR, ++ %missed beacons or better...) */ ++ __u8 level; /* signal level (dBm) */ ++ __u8 noise; /* noise level (dBm) */ ++ __u8 updated; /* Flags to know if updated */ ++}; ++ ++/* ++ * Packet discarded in the wireless adapter due to ++ * "wireless" specific problems... ++ * Note : the list of counter and statistics in net_device_stats ++ * is already pretty exhaustive, and you should use that first. ++ * This is only additional stats... ++ */ ++struct iw_discarded ++{ ++ __u32 nwid; /* Rx : Wrong nwid/essid */ ++ __u32 code; /* Rx : Unable to code/decode (WEP) */ ++ __u32 fragment; /* Rx : Can't perform MAC reassembly */ ++ __u32 retries; /* Tx : Max MAC retries num reached */ ++ __u32 misc; /* Others cases */ ++}; ++ ++/* ++ * Packet/Time period missed in the wireless adapter due to ++ * "wireless" specific problems... ++ */ ++struct iw_missed ++{ ++ __u32 beacon; /* Missed beacons/superframe */ ++}; ++ ++/* ++ * Quality range (for spy threshold) ++ */ ++struct iw_thrspy ++{ ++ struct sockaddr addr; /* Source address (hw/mac) */ ++ struct iw_quality qual; /* Quality of the link */ ++ struct iw_quality low; /* Low threshold */ ++ struct iw_quality high; /* High threshold */ ++}; ++ ++/* ++ * Optional data for scan request ++ * ++ * Note: these optional parameters are controlling parameters for the ++ * scanning behavior, these do not apply to getting scan results ++ * (SIOCGIWSCAN). Drivers are expected to keep a local BSS table and ++ * provide a merged results with all BSSes even if the previous scan ++ * request limited scanning to a subset, e.g., by specifying an SSID. ++ * Especially, scan results are required to include an entry for the ++ * current BSS if the driver is in Managed mode and associated with an AP. ++ */ ++struct iw_scan_req ++{ ++ __u8 scan_type; /* IW_SCAN_TYPE_{ACTIVE,PASSIVE} */ ++ __u8 essid_len; ++ __u8 num_channels; /* num entries in channel_list; ++ * 0 = scan all allowed channels */ ++ __u8 flags; /* reserved as padding; use zero, this may ++ * be used in the future for adding flags ++ * to request different scan behavior */ ++ struct sockaddr bssid; /* ff:ff:ff:ff:ff:ff for broadcast BSSID or ++ * individual address of a specific BSS */ ++ ++ /* ++ * Use this ESSID if IW_SCAN_THIS_ESSID flag is used instead of using ++ * the current ESSID. This allows scan requests for specific ESSID ++ * without having to change the current ESSID and potentially breaking ++ * the current association. ++ */ ++ __u8 essid[IW_ESSID_MAX_SIZE]; ++ ++ /* ++ * Optional parameters for changing the default scanning behavior. ++ * These are based on the MLME-SCAN.request from IEEE Std 802.11. ++ * TU is 1.024 ms. If these are set to 0, driver is expected to use ++ * reasonable default values. min_channel_time defines the time that ++ * will be used to wait for the first reply on each channel. If no ++ * replies are received, next channel will be scanned after this. If ++ * replies are received, total time waited on the channel is defined by ++ * max_channel_time. ++ */ ++ __u32 min_channel_time; /* in TU */ ++ __u32 max_channel_time; /* in TU */ ++ ++ struct iw_freq channel_list[IW_MAX_FREQUENCIES]; ++}; ++ ++/* ------------------------- WPA SUPPORT ------------------------- */ ++ ++/* ++ * Extended data structure for get/set encoding (this is used with ++ * SIOCSIWENCODEEXT/SIOCGIWENCODEEXT. struct iw_point and IW_ENCODE_* ++ * flags are used in the same way as with SIOCSIWENCODE/SIOCGIWENCODE and ++ * only the data contents changes (key data -> this structure, including ++ * key data). ++ * ++ * If the new key is the first group key, it will be set as the default ++ * TX key. Otherwise, default TX key index is only changed if ++ * IW_ENCODE_EXT_SET_TX_KEY flag is set. ++ * ++ * Key will be changed with SIOCSIWENCODEEXT in all cases except for ++ * special "change TX key index" operation which is indicated by setting ++ * key_len = 0 and ext_flags |= IW_ENCODE_EXT_SET_TX_KEY. ++ * ++ * tx_seq/rx_seq are only used when respective ++ * IW_ENCODE_EXT_{TX,RX}_SEQ_VALID flag is set in ext_flags. Normal ++ * TKIP/CCMP operation is to set RX seq with SIOCSIWENCODEEXT and start ++ * TX seq from zero whenever key is changed. SIOCGIWENCODEEXT is normally ++ * used only by an Authenticator (AP or an IBSS station) to get the ++ * current TX sequence number. Using TX_SEQ_VALID for SIOCSIWENCODEEXT and ++ * RX_SEQ_VALID for SIOCGIWENCODEEXT are optional, but can be useful for ++ * debugging/testing. ++ */ ++struct iw_encode_ext ++{ ++ __u32 ext_flags; /* IW_ENCODE_EXT_* */ ++ __u8 tx_seq[IW_ENCODE_SEQ_MAX_SIZE]; /* LSB first */ ++ __u8 rx_seq[IW_ENCODE_SEQ_MAX_SIZE]; /* LSB first */ ++ struct sockaddr addr; /* ff:ff:ff:ff:ff:ff for broadcast/multicast ++ * (group) keys or unicast address for ++ * individual keys */ ++ __u16 alg; /* IW_ENCODE_ALG_* */ ++ __u16 key_len; ++ __u8 key[0]; ++}; ++ ++/* SIOCSIWMLME data */ ++struct iw_mlme ++{ ++ __u16 cmd; /* IW_MLME_* */ ++ __u16 reason_code; ++ struct sockaddr addr; ++}; ++ ++/* SIOCSIWPMKSA data */ ++#define IW_PMKSA_ADD 1 ++#define IW_PMKSA_REMOVE 2 ++#define IW_PMKSA_FLUSH 3 ++ ++#define IW_PMKID_LEN 16 ++ ++struct iw_pmksa ++{ ++ __u32 cmd; /* IW_PMKSA_* */ ++ struct sockaddr bssid; ++ __u8 pmkid[IW_PMKID_LEN]; ++}; ++ ++/* IWEVMICHAELMICFAILURE data */ ++struct iw_michaelmicfailure ++{ ++ __u32 flags; ++ struct sockaddr src_addr; ++ __u8 tsc[IW_ENCODE_SEQ_MAX_SIZE]; /* LSB first */ ++}; ++ ++/* IWEVPMKIDCAND data */ ++#define IW_PMKID_CAND_PREAUTH 0x00000001 /* RNS pre-authentication enabled */ ++struct iw_pmkid_cand ++{ ++ __u32 flags; /* IW_PMKID_CAND_* */ ++ __u32 index; /* the smaller the index, the higher the ++ * priority */ ++ struct sockaddr bssid; ++}; ++ ++/* ------------------------ WIRELESS STATS ------------------------ */ ++/* ++ * Wireless statistics (used for /proc/net/wireless) ++ */ ++struct iw_statistics ++{ ++ __u16 status; /* Status ++ * - device dependent for now */ ++ ++ struct iw_quality qual; /* Quality of the link ++ * (instant/mean/max) */ ++ struct iw_discarded discard; /* Packet discarded counts */ ++ struct iw_missed miss; /* Packet missed counts */ ++}; ++ ++/* ------------------------ IOCTL REQUEST ------------------------ */ ++/* ++ * This structure defines the payload of an ioctl, and is used ++ * below. ++ * ++ * Note that this structure should fit on the memory footprint ++ * of iwreq (which is the same as ifreq), which mean a max size of ++ * 16 octets = 128 bits. Warning, pointers might be 64 bits wide... ++ * You should check this when increasing the structures defined ++ * above in this file... ++ */ ++union iwreq_data ++{ ++ /* Config - generic */ ++ char name[IFNAMSIZ]; ++ /* Name : used to verify the presence of wireless extensions. ++ * Name of the protocol/provider... */ ++ ++ struct iw_point essid; /* Extended network name */ ++ struct iw_param nwid; /* network id (or domain - the cell) */ ++ struct iw_freq freq; /* frequency or channel : ++ * 0-1000 = channel ++ * > 1000 = frequency in Hz */ ++ ++ struct iw_param sens; /* signal level threshold */ ++ struct iw_param bitrate; /* default bit rate */ ++ struct iw_param txpower; /* default transmit power */ ++ struct iw_param rts; /* RTS threshold threshold */ ++ struct iw_param frag; /* Fragmentation threshold */ ++ __u32 mode; /* Operation mode */ ++ struct iw_param retry; /* Retry limits & lifetime */ ++ ++ struct iw_point encoding; /* Encoding stuff : tokens */ ++ struct iw_param power; /* PM duration/timeout */ ++ struct iw_quality qual; /* Quality part of statistics */ ++ ++ struct sockaddr ap_addr; /* Access point address */ ++ struct sockaddr addr; /* Destination address (hw/mac) */ ++ ++ struct iw_param param; /* Other small parameters */ ++ struct iw_point data; /* Other large parameters */ ++}; ++ ++/* ++ * The structure to exchange data for ioctl. ++ * This structure is the same as 'struct ifreq', but (re)defined for ++ * convenience... ++ * Do I need to remind you about structure size (32 octets) ? ++ */ ++struct iwreq ++{ ++ union ++ { ++ char ifrn_name[IFNAMSIZ]; /* if name, e.g. "eth0" */ ++ } ifr_ifrn; ++ ++ /* Data part (defined just above) */ ++ union iwreq_data u; ++}; ++ ++/* -------------------------- IOCTL DATA -------------------------- */ ++/* ++ * For those ioctl which want to exchange mode data that what could ++ * fit in the above structure... ++ */ ++ ++/* ++ * Range of parameters ++ */ ++ ++struct iw_range ++{ ++ /* Informative stuff (to choose between different interface) */ ++ __u32 throughput; /* To give an idea... */ ++ /* In theory this value should be the maximum benchmarked ++ * TCP/IP throughput, because with most of these devices the ++ * bit rate is meaningless (overhead an co) to estimate how ++ * fast the connection will go and pick the fastest one. ++ * I suggest people to play with Netperf or any benchmark... ++ */ ++ ++ /* NWID (or domain id) */ ++ __u32 min_nwid; /* Minimal NWID we are able to set */ ++ __u32 max_nwid; /* Maximal NWID we are able to set */ ++ ++ /* Old Frequency (backward compat - moved lower ) */ ++ __u16 old_num_channels; ++ __u8 old_num_frequency; ++ ++ /* Scan capabilities */ ++ __u8 scan_capa; /* IW_SCAN_CAPA_* bit field */ ++ ++ /* Wireless event capability bitmasks */ ++ __u32 event_capa[6]; ++ ++ /* signal level threshold range */ ++ __s32 sensitivity; ++ ++ /* Quality of link & SNR stuff */ ++ /* Quality range (link, level, noise) ++ * If the quality is absolute, it will be in the range [0 ; max_qual], ++ * if the quality is dBm, it will be in the range [max_qual ; 0]. ++ * Don't forget that we use 8 bit arithmetics... */ ++ struct iw_quality max_qual; /* Quality of the link */ ++ /* This should contain the average/typical values of the quality ++ * indicator. This should be the threshold between a "good" and ++ * a "bad" link (example : monitor going from green to orange). ++ * Currently, user space apps like quality monitors don't have any ++ * way to calibrate the measurement. With this, they can split ++ * the range between 0 and max_qual in different quality level ++ * (using a geometric subdivision centered on the average). ++ * I expect that people doing the user space apps will feedback ++ * us on which value we need to put in each driver... */ ++ struct iw_quality avg_qual; /* Quality of the link */ ++ ++ /* Rates */ ++ __u8 num_bitrates; /* Number of entries in the list */ ++ __s32 bitrate[IW_MAX_BITRATES]; /* list, in bps */ ++ ++ /* RTS threshold */ ++ __s32 min_rts; /* Minimal RTS threshold */ ++ __s32 max_rts; /* Maximal RTS threshold */ ++ ++ /* Frag threshold */ ++ __s32 min_frag; /* Minimal frag threshold */ ++ __s32 max_frag; /* Maximal frag threshold */ ++ ++ /* Power Management duration & timeout */ ++ __s32 min_pmp; /* Minimal PM period */ ++ __s32 max_pmp; /* Maximal PM period */ ++ __s32 min_pmt; /* Minimal PM timeout */ ++ __s32 max_pmt; /* Maximal PM timeout */ ++ __u16 pmp_flags; /* How to decode max/min PM period */ ++ __u16 pmt_flags; /* How to decode max/min PM timeout */ ++ __u16 pm_capa; /* What PM options are supported */ ++ ++ /* Encoder stuff */ ++ __u16 encoding_size[IW_MAX_ENCODING_SIZES]; /* Different token sizes */ ++ __u8 num_encoding_sizes; /* Number of entry in the list */ ++ __u8 max_encoding_tokens; /* Max number of tokens */ ++ /* For drivers that need a "login/passwd" form */ ++ __u8 encoding_login_index; /* token index for login token */ ++ ++ /* Transmit power */ ++ __u16 txpower_capa; /* What options are supported */ ++ __u8 num_txpower; /* Number of entries in the list */ ++ __s32 txpower[IW_MAX_TXPOWER]; /* list, in bps */ ++ ++ /* Wireless Extension version info */ ++ __u8 we_version_compiled; /* Must be WIRELESS_EXT */ ++ __u8 we_version_source; /* Last update of source */ ++ ++ /* Retry limits and lifetime */ ++ __u16 retry_capa; /* What retry options are supported */ ++ __u16 retry_flags; /* How to decode max/min retry limit */ ++ __u16 r_time_flags; /* How to decode max/min retry life */ ++ __s32 min_retry; /* Minimal number of retries */ ++ __s32 max_retry; /* Maximal number of retries */ ++ __s32 min_r_time; /* Minimal retry lifetime */ ++ __s32 max_r_time; /* Maximal retry lifetime */ ++ ++ /* Frequency */ ++ __u16 num_channels; /* Number of channels [0; num - 1] */ ++ __u8 num_frequency; /* Number of entry in the list */ ++ struct iw_freq freq[IW_MAX_FREQUENCIES]; /* list */ ++ /* Note : this frequency list doesn't need to fit channel numbers, ++ * because each entry contain its channel index */ ++ ++ __u32 enc_capa; /* IW_ENC_CAPA_* bit field */ ++}; ++ ++/* ++ * Private ioctl interface information ++ */ ++ ++struct iw_priv_args ++{ ++ __u32 cmd; /* Number of the ioctl to issue */ ++ __u16 set_args; /* Type and number of args */ ++ __u16 get_args; /* Type and number of args */ ++ char name[IFNAMSIZ]; /* Name of the extension */ ++}; ++ ++/* ----------------------- WIRELESS EVENTS ----------------------- */ ++/* ++ * Wireless events are carried through the rtnetlink socket to user ++ * space. They are encapsulated in the IFLA_WIRELESS field of ++ * a RTM_NEWLINK message. ++ */ ++ ++/* ++ * A Wireless Event. Contains basically the same data as the ioctl... ++ */ ++struct iw_event ++{ ++ __u16 len; /* Real length of this stuff */ ++ __u16 cmd; /* Wireless IOCTL */ ++ union iwreq_data u; /* IOCTL fixed payload */ ++}; ++ ++/* Size of the Event prefix (including padding and alignement junk) */ ++#define IW_EV_LCP_LEN (sizeof(struct iw_event) - sizeof(union iwreq_data)) ++/* Size of the various events */ ++#define IW_EV_CHAR_LEN (IW_EV_LCP_LEN + IFNAMSIZ) ++#define IW_EV_UINT_LEN (IW_EV_LCP_LEN + sizeof(__u32)) ++#define IW_EV_FREQ_LEN (IW_EV_LCP_LEN + sizeof(struct iw_freq)) ++#define IW_EV_PARAM_LEN (IW_EV_LCP_LEN + sizeof(struct iw_param)) ++#define IW_EV_ADDR_LEN (IW_EV_LCP_LEN + sizeof(struct sockaddr)) ++#define IW_EV_QUAL_LEN (IW_EV_LCP_LEN + sizeof(struct iw_quality)) ++ ++/* iw_point events are special. First, the payload (extra data) come at ++ * the end of the event, so they are bigger than IW_EV_POINT_LEN. Second, ++ * we omit the pointer, so start at an offset. */ ++#define IW_EV_POINT_OFF (((char *) &(((struct iw_point *) NULL)->length)) - \ ++ (char *) NULL) ++#define IW_EV_POINT_LEN (IW_EV_LCP_LEN + sizeof(struct iw_point) - \ ++ IW_EV_POINT_OFF) ++ ++#ifdef __KERNEL__ ++#ifdef CONFIG_COMPAT ++struct __compat_iw_event { ++ __u16 len; /* Real length of this stuff */ ++ __u16 cmd; /* Wireless IOCTL */ ++ compat_caddr_t pointer; ++}; ++#define IW_EV_COMPAT_LCP_LEN offsetof(struct __compat_iw_event, pointer) ++#define IW_EV_COMPAT_POINT_OFF offsetof(struct compat_iw_point, length) ++ ++/* Size of the various events for compat */ ++#define IW_EV_COMPAT_CHAR_LEN (IW_EV_COMPAT_LCP_LEN + IFNAMSIZ) ++#define IW_EV_COMPAT_UINT_LEN (IW_EV_COMPAT_LCP_LEN + sizeof(__u32)) ++#define IW_EV_COMPAT_FREQ_LEN (IW_EV_COMPAT_LCP_LEN + sizeof(struct iw_freq)) ++#define IW_EV_COMPAT_PARAM_LEN (IW_EV_COMPAT_LCP_LEN + sizeof(struct iw_param)) ++#define IW_EV_COMPAT_ADDR_LEN (IW_EV_COMPAT_LCP_LEN + sizeof(struct sockaddr)) ++#define IW_EV_COMPAT_QUAL_LEN (IW_EV_COMPAT_LCP_LEN + sizeof(struct iw_quality)) ++#define IW_EV_COMPAT_POINT_LEN \ ++ (IW_EV_COMPAT_LCP_LEN + sizeof(struct compat_iw_point) - \ ++ IW_EV_COMPAT_POINT_OFF) ++#endif ++#endif ++ ++/* Size of the Event prefix when packed in stream */ ++#define IW_EV_LCP_PK_LEN (4) ++/* Size of the various events when packed in stream */ ++#define IW_EV_CHAR_PK_LEN (IW_EV_LCP_PK_LEN + IFNAMSIZ) ++#define IW_EV_UINT_PK_LEN (IW_EV_LCP_PK_LEN + sizeof(__u32)) ++#define IW_EV_FREQ_PK_LEN (IW_EV_LCP_PK_LEN + sizeof(struct iw_freq)) ++#define IW_EV_PARAM_PK_LEN (IW_EV_LCP_PK_LEN + sizeof(struct iw_param)) ++#define IW_EV_ADDR_PK_LEN (IW_EV_LCP_PK_LEN + sizeof(struct sockaddr)) ++#define IW_EV_QUAL_PK_LEN (IW_EV_LCP_PK_LEN + sizeof(struct iw_quality)) ++#define IW_EV_POINT_PK_LEN (IW_EV_LCP_PK_LEN + 4) ++ ++#endif /* _LINUX_WIRELESS_H */ diff --cc compat/include/net/codel.h index 000000000000,000000000000..eee0359cd6e5 new file mode 100644 --- /dev/null +++ b/compat/include/net/codel.h @@@ -1,0 -1,0 +1,363 @@@ ++#include ++#include ++ ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)) || (defined(TCA_CODEL_MAX) && !defined(COMPAT_CODEL_BACKPORT)) ++#include_next ++#else ++ ++#ifndef __NET_SCHED_CODEL_H ++#define __NET_SCHED_CODEL_H ++ ++/* ++ * Codel - The Controlled-Delay Active Queue Management algorithm ++ * ++ * Copyright (C) 2011-2012 Kathleen Nichols ++ * Copyright (C) 2011-2012 Van Jacobson ++ * Copyright (C) 2012 Michael D. Taht ++ * Copyright (C) 2012 Eric Dumazet ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions, and the following disclaimer, ++ * without modification. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * 3. The names of the authors may not be used to endorse or promote products ++ * derived from this software without specific prior written permission. ++ * ++ * Alternatively, provided that this notice is retained in full, this ++ * software may be distributed under the terms of the GNU General ++ * Public License ("GPL") version 2, in which case the provisions of the ++ * GPL apply INSTEAD OF those given above. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH ++ * DAMAGE. ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* Controlling Queue Delay (CoDel) algorithm ++ * ========================================= ++ * Source : Kathleen Nichols and Van Jacobson ++ * http://queue.acm.org/detail.cfm?id=2209336 ++ * ++ * Implemented on linux by Dave Taht and Eric Dumazet ++ */ ++ ++ ++/* CoDel uses a 1024 nsec clock, encoded in u32 ++ * This gives a range of 2199 seconds, because of signed compares ++ */ ++typedef u32 codel_time_t; ++typedef s32 codel_tdiff_t; ++#define CODEL_SHIFT 10 ++#define MS2TIME(a) ((a * NSEC_PER_MSEC) >> CODEL_SHIFT) ++ ++static inline codel_time_t codel_get_time(void) ++{ ++ u64 ns = ktime_to_ns(ktime_get()); ++ ++ return ns >> CODEL_SHIFT; ++} ++ ++#define codel_time_after(a, b) ((s32)(a) - (s32)(b) > 0) ++#define codel_time_after_eq(a, b) ((s32)(a) - (s32)(b) >= 0) ++#define codel_time_before(a, b) ((s32)(a) - (s32)(b) < 0) ++#define codel_time_before_eq(a, b) ((s32)(a) - (s32)(b) <= 0) ++ ++/* Qdiscs using codel plugin must use codel_skb_cb in their own cb[] */ ++struct codel_skb_cb { ++ codel_time_t enqueue_time; ++}; ++ ++static struct codel_skb_cb *get_codel_cb(const struct sk_buff *skb) ++{ ++ qdisc_cb_private_validate(skb, sizeof(struct codel_skb_cb)); ++#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,37)) ++ return (struct codel_skb_cb *)qdisc_skb_cb((struct sk_buff *) skb)->data; ++#else ++ return (struct codel_skb_cb *)qdisc_skb_cb(skb)->data; ++#endif ++} ++ ++static codel_time_t codel_get_enqueue_time(const struct sk_buff *skb) ++{ ++ return get_codel_cb(skb)->enqueue_time; ++} ++ ++static void codel_set_enqueue_time(struct sk_buff *skb) ++{ ++ get_codel_cb(skb)->enqueue_time = codel_get_time(); ++} ++ ++static inline u32 codel_time_to_us(codel_time_t val) ++{ ++ u64 valns = ((u64)val << CODEL_SHIFT); ++ ++ do_div(valns, NSEC_PER_USEC); ++ return (u32)valns; ++} ++ ++/** ++ * struct codel_params - contains codel parameters ++ * @target: target queue size (in time units) ++ * @interval: width of moving time window ++ * @ecn: is Explicit Congestion Notification enabled ++ */ ++struct codel_params { ++ codel_time_t target; ++ codel_time_t interval; ++ bool ecn; ++}; ++ ++/** ++ * struct codel_vars - contains codel variables ++ * @count: how many drops we've done since the last time we ++ * entered dropping state ++ * @lastcount: count at entry to dropping state ++ * @dropping: set to true if in dropping state ++ * @rec_inv_sqrt: reciprocal value of sqrt(count) >> 1 ++ * @first_above_time: when we went (or will go) continuously above target ++ * for interval ++ * @drop_next: time to drop next packet, or when we dropped last ++ * @ldelay: sojourn time of last dequeued packet ++ */ ++struct codel_vars { ++ u32 count; ++ u32 lastcount; ++ bool dropping; ++ u16 rec_inv_sqrt; ++ codel_time_t first_above_time; ++ codel_time_t drop_next; ++ codel_time_t ldelay; ++}; ++ ++#define REC_INV_SQRT_BITS (8 * sizeof(u16)) /* or sizeof_in_bits(rec_inv_sqrt) */ ++/* needed shift to get a Q0.32 number from rec_inv_sqrt */ ++#define REC_INV_SQRT_SHIFT (32 - REC_INV_SQRT_BITS) ++ ++/** ++ * struct codel_stats - contains codel shared variables and stats ++ * @maxpacket: largest packet we've seen so far ++ * @drop_count: temp count of dropped packets in dequeue() ++ * ecn_mark: number of packets we ECN marked instead of dropping ++ */ ++struct codel_stats { ++ u32 maxpacket; ++ u32 drop_count; ++ u32 ecn_mark; ++}; ++ ++static void codel_params_init(struct codel_params *params) ++{ ++ params->interval = MS2TIME(100); ++ params->target = MS2TIME(5); ++ params->ecn = false; ++} ++ ++static void codel_vars_init(struct codel_vars *vars) ++{ ++ memset(vars, 0, sizeof(*vars)); ++} ++ ++static void codel_stats_init(struct codel_stats *stats) ++{ ++ stats->maxpacket = 256; ++} ++ ++/* ++ * http://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Iterative_methods_for_reciprocal_square_roots ++ * new_invsqrt = (invsqrt / 2) * (3 - count * invsqrt^2) ++ * ++ * Here, invsqrt is a fixed point number (< 1.0), 32bit mantissa, aka Q0.32 ++ */ ++static void codel_Newton_step(struct codel_vars *vars) ++{ ++ u32 invsqrt = ((u32)vars->rec_inv_sqrt) << REC_INV_SQRT_SHIFT; ++ u32 invsqrt2 = ((u64)invsqrt * invsqrt) >> 32; ++ u64 val = (3LL << 32) - ((u64)vars->count * invsqrt2); ++ ++ val >>= 2; /* avoid overflow in following multiply */ ++ val = (val * invsqrt) >> (32 - 2 + 1); ++ ++ vars->rec_inv_sqrt = val >> REC_INV_SQRT_SHIFT; ++} ++ ++/* ++ * CoDel control_law is t + interval/sqrt(count) ++ * We maintain in rec_inv_sqrt the reciprocal value of sqrt(count) to avoid ++ * both sqrt() and divide operation. ++ */ ++static codel_time_t codel_control_law(codel_time_t t, ++ codel_time_t interval, ++ u32 rec_inv_sqrt) ++{ ++ return t + reciprocal_divide(interval, rec_inv_sqrt << REC_INV_SQRT_SHIFT); ++} ++ ++ ++static bool codel_should_drop(const struct sk_buff *skb, ++ struct Qdisc *sch, ++ struct codel_vars *vars, ++ struct codel_params *params, ++ struct codel_stats *stats, ++ codel_time_t now) ++{ ++ bool ok_to_drop; ++ ++ if (!skb) { ++ vars->first_above_time = 0; ++ return false; ++ } ++ ++ vars->ldelay = now - codel_get_enqueue_time(skb); ++#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,37)) ++ sch->qstats.backlog -= qdisc_pkt_len((struct sk_buff *)skb); ++#else ++ sch->qstats.backlog -= qdisc_pkt_len(skb); ++#endif ++ ++#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,37)) ++ if (unlikely(qdisc_pkt_len((struct sk_buff *)skb) > stats->maxpacket)) ++ stats->maxpacket = qdisc_pkt_len((struct sk_buff *)skb); ++#else ++ if (unlikely(qdisc_pkt_len(skb) > stats->maxpacket)) ++ stats->maxpacket = qdisc_pkt_len(skb); ++#endif ++ ++ if (codel_time_before(vars->ldelay, params->target) || ++ sch->qstats.backlog <= stats->maxpacket) { ++ /* went below - stay below for at least interval */ ++ vars->first_above_time = 0; ++ return false; ++ } ++ ok_to_drop = false; ++ if (vars->first_above_time == 0) { ++ /* just went above from below. If we stay above ++ * for at least interval we'll say it's ok to drop ++ */ ++ vars->first_above_time = now + params->interval; ++ } else if (codel_time_after(now, vars->first_above_time)) { ++ ok_to_drop = true; ++ } ++ return ok_to_drop; ++} ++ ++typedef struct sk_buff * (*codel_skb_dequeue_t)(struct codel_vars *vars, ++ struct Qdisc *sch); ++ ++static struct sk_buff *codel_dequeue(struct Qdisc *sch, ++ struct codel_params *params, ++ struct codel_vars *vars, ++ struct codel_stats *stats, ++ codel_skb_dequeue_t dequeue_func) ++{ ++ struct sk_buff *skb = dequeue_func(vars, sch); ++ codel_time_t now; ++ bool drop; ++ ++ if (!skb) { ++ vars->dropping = false; ++ return skb; ++ } ++ now = codel_get_time(); ++ drop = codel_should_drop(skb, sch, vars, params, stats, now); ++ if (vars->dropping) { ++ if (!drop) { ++ /* sojourn time below target - leave dropping state */ ++ vars->dropping = false; ++ } else if (codel_time_after_eq(now, vars->drop_next)) { ++ /* It's time for the next drop. Drop the current ++ * packet and dequeue the next. The dequeue might ++ * take us out of dropping state. ++ * If not, schedule the next drop. ++ * A large backlog might result in drop rates so high ++ * that the next drop should happen now, ++ * hence the while loop. ++ */ ++ while (vars->dropping && ++ codel_time_after_eq(now, vars->drop_next)) { ++ vars->count++; /* dont care of possible wrap ++ * since there is no more divide ++ */ ++ codel_Newton_step(vars); ++ if (params->ecn && INET_ECN_set_ce(skb)) { ++ stats->ecn_mark++; ++ vars->drop_next = ++ codel_control_law(vars->drop_next, ++ params->interval, ++ vars->rec_inv_sqrt); ++ goto end; ++ } ++ qdisc_drop(skb, sch); ++ stats->drop_count++; ++ skb = dequeue_func(vars, sch); ++ if (!codel_should_drop(skb, sch, ++ vars, params, stats, now)) { ++ /* leave dropping state */ ++ vars->dropping = false; ++ } else { ++ /* and schedule the next drop */ ++ vars->drop_next = ++ codel_control_law(vars->drop_next, ++ params->interval, ++ vars->rec_inv_sqrt); ++ } ++ } ++ } ++ } else if (drop) { ++ if (params->ecn && INET_ECN_set_ce(skb)) { ++ stats->ecn_mark++; ++ } else { ++ qdisc_drop(skb, sch); ++ stats->drop_count++; ++ ++ skb = dequeue_func(vars, sch); ++ drop = codel_should_drop(skb, sch, vars, params, ++ stats, now); ++ } ++ vars->dropping = true; ++ /* if min went above target close to when we last went below it ++ * assume that the drop rate that controlled the queue on the ++ * last cycle is a good starting point to control it now. ++ */ ++ if (codel_time_before(now - vars->drop_next, ++ 16 * params->interval)) { ++ vars->count = (vars->count - vars->lastcount) | 1; ++ /* we dont care if rec_inv_sqrt approximation ++ * is not very precise : ++ * Next Newton steps will correct it quadratically. ++ */ ++ codel_Newton_step(vars); ++ } else { ++ vars->count = 1; ++ vars->rec_inv_sqrt = ~0U >> REC_INV_SQRT_SHIFT; ++ } ++ vars->lastcount = vars->count; ++ vars->drop_next = codel_control_law(now, params->interval, ++ vars->rec_inv_sqrt); ++ } ++end: ++ return skb; ++} ++#endif ++#endif diff --cc compat/include/net/flow_keys.h index 000000000000,000000000000..a875ee6eeb3b new file mode 100644 --- /dev/null +++ b/compat/include/net/flow_keys.h @@@ -1,0 -1,0 +1,21 @@@ ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0)) ++#include_next ++#else ++ ++#ifndef _NET_FLOW_KEYS_H ++#define _NET_FLOW_KEYS_H ++ ++struct flow_keys { ++ /* (src,dst) must be grouped, in the same way than in IP header */ ++ __be32 src; ++ __be32 dst; ++ union { ++ __be32 ports; ++ __be16 port16[2]; ++ }; ++ u8 ip_proto; ++}; ++ ++extern bool skb_flow_dissect(const struct sk_buff *skb, struct flow_keys *flow); ++#endif ++#endif diff --cc compat/include/net/net_namespace.h index 000000000000,000000000000..0f74944b3823 new file mode 100644 --- /dev/null +++ b/compat/include/net/net_namespace.h @@@ -1,0 -1,0 +1,10 @@@ ++#ifndef _COMPAT_NET_NET_NAMESPACE_H ++#define _COMPAT_NET_NET_NAMESPACE_H 1 ++ ++#include ++ ++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,23)) ++#include_next ++#endif /* (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,23)) */ ++ ++#endif /* _COMPAT_NET_NET_NAMESPACE_H */ diff --cc compat/include/pcmcia/cistpl.h index 000000000000,000000000000..789dc59db726 new file mode 100644 --- /dev/null +++ b/compat/include/pcmcia/cistpl.h @@@ -1,0 -1,0 +1,10 @@@ ++#include ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36) ++#include ++#endif ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,37) ++#include ++#endif ++ ++#include_next diff --cc compat/include/trace/define_trace.h index 000000000000,000000000000..7d03ccf770e5 new file mode 100644 --- /dev/null +++ b/compat/include/trace/define_trace.h @@@ -1,0 -1,0 +1,5 @@@ ++#include ++ ++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,30)) ++#include_next ++#endif /* (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,30)) */ diff --cc compat/scripts/compat_firmware_install index 000000000000,000000000000..e4b9fb03835d new file mode 100755 --- /dev/null +++ b/compat/scripts/compat_firmware_install @@@ -1,0 -1,0 +1,21 @@@ ++#!/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/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 ++ diff --cc compat/scripts/gen-compat-autoconf.sh index 000000000000,000000000000..e52cc5aa8807 new file mode 100755 --- /dev/null +++ b/compat/scripts/gen-compat-autoconf.sh @@@ -1,0 -1,0 +1,105 @@@ ++#!/bin/bash ++# ++# Copyright 2012 Luis R. Rodriguez ++# Copyright 2011 Hauke Mehrtens ++# Copyright 2011 John W. Linville ++# ++# Use this to parse a small .config equivalent looking file to generate ++# our own autoconf.h. This file has defines for each config option ++# just like the kernels include/linux/autoconf.h ++# ++# XXX: consider using scripts/kconfig/confdata.c instead. ++# On the downside this would require the user to have libc though. ++ ++# This indicates which is the oldest kernel we support ++# Update this if you are adding support for older kernels. ++OLDEST_KERNEL_SUPPORTED="2.6.24" ++ ++if [ $# -ne 1 ]; then ++ echo "Usage $0 config-file" ++ exit ++fi ++ ++COMPAT_CONFIG="$1" ++ ++if [ ! -f $COMPAT_CONFIG ]; then ++ echo "File $1 is not a file" ++ exit ++fi ++ ++# Defines a CONFIG_ option if not defined yet, this helps respect ++# linux/autoconf.h ++function define_config { ++ VAR=$1 ++ VALUE=$2 ++ case $VALUE in ++ n) # Try to undefine it ++ echo "#undef $VAR" ++ ;; ++ y) ++ echo "#ifndef $VAR" ++ echo "#define $VAR 1" ++ echo "#endif /* $VAR */" ++ ;; ++ m) ++ echo "#ifndef $VAR" ++ echo "#define $VAR 1" ++ echo "#endif /* $VAR */" ++ ;; ++ *) # Assume string ++ # XXX: add better checks to make sure what was on ++ # the right was indeed a string ++ echo "#ifndef $VAR" ++ echo "#define $VAR \"$VALUE\"" ++ echo "#endif /* $VAR */" ++ ;; ++ esac ++} ++ ++function kernel_version_req { ++ VERSION=$(echo $1 | sed -e 's/\./,/g') ++ echo "#if (LINUX_VERSION_CODE < KERNEL_VERSION($VERSION))" ++ echo "#error compat requirement: Linux >= $VERSION" ++ echo "#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION($VERSION) */" ++} ++ ++cat <= \3)/' -e 's/\(#ifdef \)\(CONFIG_[^:space:]*\)/#if defined(\2) || defined(\2_MODULE)/' ++ continue ++ ;; ++ 'ifndef+CONFIG_'* ) ++ echo "#$i" | sed -e 's/+/ /' -e 's/\(ifndef CONFIG_COMPAT_KERNEL_3_\)\([0-9]*\)/if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,\2,0))/' -e 's/\(ifndef CONFIG_COMPAT_KERNEL_2_6_\)\([0-9]*\)/if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,\2))/' -e 's/\(ifndef CONFIG_COMPAT_RHEL_\)\([0-9]*\)_\([0-9]*\)/if (!defined(RHEL_MAJOR) || RHEL_MAJOR != \2 || RHEL_MINOR < \3)/' -e 's/\(#ifndef \)\(CONFIG_[^:space:]*\)/#if !defined(\2) \&\& !defined(\2_MODULE)/' ++ continue ++ ;; ++ 'else+#CONFIG_'* | 'endif+#CONFIG_'* ) ++ echo "#$i */" |sed -e 's/+#/ \/* /g' ++ continue ++ ;; ++ CONFIG_* ) ++ # Get the element on the left of the "=" ++ VAR=$(echo $i | cut -d"=" -f 1) ++ # Get the element on the right of the "=" ++ VALUE=$(echo $i | cut -d"=" -f 2) ++ ++ # Any other module which can *definitely* be built as a module goes here ++ define_config $VAR $VALUE ++ continue ++ ;; ++ esac ++done ++ ++echo "#endif /* COMPAT_AUTOCONF_INCLUDED */" diff --cc compat/scripts/gen-compat-config.sh index 000000000000,000000000000..8dd6f4c4f6ea new file mode 100755 --- /dev/null +++ b/compat/scripts/gen-compat-config.sh @@@ -1,0 -1,0 +1,81 @@@ ++#!/bin/bash ++# Copyright 2012 Luis R. Rodriguez ++# Copyright 2012 Hauke Mehrtens ++# ++# This generates a bunch of CONFIG_COMPAT_KERNEL_2_6_22 ++# CONFIG_COMPAT_KERNEL_3_0 .. etc for each kernel release you need an object ++# for. ++# ++# Note: this is part of the compat.git project, not compat-drivers, ++# send patches against compat.git. ++ ++if [[ ! -f ${KLIB_BUILD}/Makefile ]]; then ++ exit ++fi ++ ++# Actual kernel version ++KERNEL_VERSION=$(${MAKE} -C ${KLIB_BUILD} kernelversion | sed -n 's/^\([0-9]\)\..*/\1/p') ++ ++# 3.0 kernel stuff ++COMPAT_LATEST_VERSION="9" ++KERNEL_SUBLEVEL="-1" ++ ++# Note that this script will export all variables explicitly, ++# trying to export all with a blanket "export" statement at ++# the top of the generated file causes the build to slow down ++# by an order of magnitude. ++ ++if [[ ${KERNEL_VERSION} -eq "3" ]]; then ++ KERNEL_SUBLEVEL=$(${MAKE} -C ${KLIB_BUILD} kernelversion | sed -n 's/^3\.\([0-9]\+\).*/\1/p') ++else ++ COMPAT_26LATEST_VERSION="39" ++ KERNEL_26SUBLEVEL=$(${MAKE} -C ${KLIB_BUILD} kernelversion | sed -n 's/^2\.6\.\([0-9]\+\).*/\1/p') ++ let KERNEL_26SUBLEVEL=${KERNEL_26SUBLEVEL}+1 ++ ++ for i in $(seq ${KERNEL_26SUBLEVEL} ${COMPAT_26LATEST_VERSION}); do ++ eval CONFIG_COMPAT_KERNEL_2_6_${i}=y ++ echo "export CONFIG_COMPAT_KERNEL_2_6_${i}=y" ++ done ++fi ++ ++let KERNEL_SUBLEVEL=${KERNEL_SUBLEVEL}+1 ++for i in $(seq ${KERNEL_SUBLEVEL} ${COMPAT_LATEST_VERSION}); do ++ eval CONFIG_COMPAT_KERNEL_3_${i}=y ++ echo "export CONFIG_COMPAT_KERNEL_3_${i}=y" ++done ++ ++# The purpose of these seem to be the inverse of the above other varibales. ++# The RHEL checks seem to annotate the existance of RHEL minor versions. ++RHEL_MAJOR=$(grep ^RHEL_MAJOR ${KLIB_BUILD}/Makefile | sed -n 's/.*= *\(.*\)/\1/p') ++if [[ ! -z ${RHEL_MAJOR} ]]; then ++ RHEL_MINOR=$(grep ^RHEL_MINOR ${KLIB_BUILD}/Makefile | sed -n 's/.*= *\(.*\)/\1/p') ++ for i in $(seq 0 ${RHEL_MINOR}); do ++ eval CONFIG_COMPAT_RHEL_${RHEL_MAJOR}_${i}=y ++ echo "export CONFIG_COMPAT_RHEL_${RHEL_MAJOR}_${i}=y" ++ done ++fi ++ ++if [[ ${CONFIG_COMPAT_KERNEL_2_6_33} = "y" ]]; then ++ if [[ ! ${CONFIG_COMPAT_RHEL_6_0} = "y" ]]; then ++ echo "export CONFIG_COMPAT_FIRMWARE_CLASS=m" ++ fi ++fi ++ ++if [[ ${CONFIG_COMPAT_KERNEL_2_6_36} = "y" ]]; then ++ if [[ ! ${CONFIG_COMPAT_RHEL_6_1} = "y" ]]; then ++ echo "export CONFIG_COMPAT_KFIFO=y" ++ fi ++fi ++ ++if [[ ${CONFIG_COMPAT_KERNEL_3_5} = "y" ]]; then ++ # We don't have 2.6.24 backport support yet for Codel / FQ CoDel ++ # For those who want to try this is what is required that I can tell ++ # so far: ++ # * struct Qdisc_ops ++ # - init and change callback ops use a different argument dataype ++ # - you need to parse data received from userspace differently ++ if [[ ${CONFIG_COMPAT_KERNEL_2_6_25} != "y" ]]; then ++ echo "export CONFIG_COMPAT_NET_SCH_CODEL=m" ++ echo "export CONFIG_COMPAT_NET_SCH_FQ_CODEL=m" ++ fi ++fi diff --cc compat/scripts/skip-colors index 000000000000,000000000000..121626fb161c new file mode 100755 --- /dev/null +++ b/compat/scripts/skip-colors @@@ -1,0 -1,0 +1,2 @@@ ++#!/bin/bash ++perl -pe 's|(\e)\[(\d+)(;*)(\d*)(\w)||g' diff --cc compat/udev/50-compat_firmware.rules index 000000000000,000000000000..6473788ec464 new file mode 100644 --- /dev/null +++ b/compat/udev/50-compat_firmware.rules @@@ -1,0 -1,0 +1,4 @@@ ++# do not edit this file, it will be overwritten on update ++ ++# compat_firmware-class requests, copies files into the kernel ++SUBSYSTEM=="compat_firmware", ACTION=="add", RUN+="compat_firmware.sh" diff --cc compat/udev/compat_firmware.sh index 000000000000,000000000000..ef609e71c6df new file mode 100755 --- /dev/null +++ b/compat/udev/compat_firmware.sh @@@ -1,0 -1,0 +1,35 @@@ ++#!/bin/sh -e ++ ++# This is ported from Ubuntu but ubuntu uses these directories which ++# other distributions don't care about: ++# FIRMWARE_DIRS="/lib/firmware/updates/$(uname -r) /lib/firmware/updates \ ++# /lib/firmware/$(uname -r) /lib/firmware" ++# If your distribution looks for firmware in other directories ++# feel free to extend this and add your own directory here. ++# ++FIRMWARE_DIRS="/lib/firmware" ++ ++err() { ++ echo "$@" >&2 ++ logger -t "${0##*/}[$$]" "$@" 2>/dev/null || true ++} ++ ++if [ ! -e /sys$DEVPATH/loading ]; then ++ err "udev firmware loader misses sysfs directory" ++ exit 1 ++fi ++ ++for DIR in $FIRMWARE_DIRS; do ++ [ -e "$DIR/$FIRMWARE" ] || continue ++ echo 1 > /sys$DEVPATH/loading ++ cat "$DIR/$FIRMWARE" > /sys$DEVPATH/data ++ echo 0 > /sys$DEVPATH/loading ++ exit 0 ++done ++ ++echo -1 > /sys$DEVPATH/loading ++err "Cannot find firmware file '$FIRMWARE'" ++mkdir -p /dev/.udev/firmware-missing ++file=$(echo "$FIRMWARE" | sed 's:/:\\x2f:g') ++ln -s -f "$DEVPATH" /dev/.udev/firmware-missing/$file ++exit 1 diff --cc compat/udev/ubuntu/compat_firmware.sh index 000000000000,000000000000..9d4659a34d78 new file mode 100755 --- /dev/null +++ b/compat/udev/ubuntu/compat_firmware.sh @@@ -1,0 -1,0 +1,29 @@@ ++#!/bin/sh -e ++ ++FIRMWARE_DIRS="/lib/firmware/updates/$(uname -r) /lib/firmware/updates \ ++ /lib/firmware/$(uname -r) /lib/firmware" ++ ++err() { ++ echo "$@" >&2 ++ logger -t "${0##*/}[$$]" "$@" 2>/dev/null || true ++} ++ ++if [ ! -e /sys$DEVPATH/loading ]; then ++ err "udev firmware loader misses sysfs directory" ++ exit 1 ++fi ++ ++for DIR in $FIRMWARE_DIRS; do ++ [ -e "$DIR/$FIRMWARE" ] || continue ++ echo 1 > /sys$DEVPATH/loading ++ cat "$DIR/$FIRMWARE" > /sys$DEVPATH/data ++ echo 0 > /sys$DEVPATH/loading ++ exit 0 ++done ++ ++echo -1 > /sys$DEVPATH/loading ++err "Cannot find firmware file '$FIRMWARE'" ++mkdir -p /dev/.udev/firmware-missing ++file=$(echo "$FIRMWARE" | sed 's:/:\\x2f:g') ++ln -s -f "$DEVPATH" /dev/.udev/firmware-missing/$file ++exit 1